Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
Support accessing strings in arrays via index and wildcard (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
fsteeg committed Nov 25, 2021
1 parent bd902fd commit 7b0cc12
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 31 deletions.
49 changes: 45 additions & 4 deletions metafix/src/main/java/org/metafacture/metafix/Value.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ public static boolean isNull(final Value value) {
return value == null || value.isNull();
}

private static boolean isNumber(final String s) {
return s.matches("\\d+");
}

public Array asArray() {
if (isArray()) {
return array;
Expand Down Expand Up @@ -292,6 +296,21 @@ public String asString() {
return list.toString();
}

public void remove(final int index) {
list.remove(index);
}

private void removeNested(final String[] fields, final Value value) {
if (fields.length > 1 && isNumber(fields[1])) {
final int index = Integer.parseInt(fields[1]) - 1;
if (index >= 0 && index < value.asArray().size()) {
if (value.asArray().get(index).isString()) {
value.asArray().remove(index);
}
}
}
}

}

/**
Expand Down Expand Up @@ -397,7 +416,18 @@ private Value find(final String[] fields) {
private Value findNested(final String field, final String[] remainingFields) {
final Value value = get(field);

// TODO: array of maps, like in insert nested
if (value.isArray()) {
if (remainingFields.length > 0 && isNumber(remainingFields[0])) {
final int index = Integer.parseInt(remainingFields[0]) - 1;
if (index >= 0 && index < value.asArray().size()) {
final Value nestedValue = value.asArray().get(index);
if (nestedValue.isString()) {
return nestedValue;
}
// TODO: array of maps, like in insert nested
}
}
}

if (value.isHash()) {
return value.asHash().find(remainingFields);
Expand Down Expand Up @@ -467,7 +497,12 @@ else if (value.isArray()) {
}
break;
default:
array.add(newHash(h -> h.insert(mode, remainingFields, newValue)));
if (isNumber(remainingFields[0])) {
array.add(new Value(newValue));
}
else {
array.add(newHash(h -> h.insert(mode, remainingFields, newValue)));
}
break;
}
}
Expand Down Expand Up @@ -499,7 +534,13 @@ private void removeNested(final String[] fields) {
remove(field);
}
else if (containsField(field)) {
get(field).asHash().removeNested(Arrays.copyOfRange(fields, 1, fields.length));
final Value value = get(field);
if (value.isArray()) {
value.asArray().removeNested(fields, value);
}
if (value.isHash()) {
value.asHash().removeNested(Arrays.copyOfRange(fields, 1, fields.length));
}
}
}

Expand All @@ -510,7 +551,7 @@ public void copy(final List<String> params) {
}

public void transformFields(final List<String> params, final UnaryOperator<String> operator) {
final String field = params.get(0);
final String field = params.get(0).replace(".*", "");
final Value value = find(field);

if (value != null) {
Expand Down
165 changes: 138 additions & 27 deletions metafix/src/test/java/org/metafacture/metafix/MetafixRecordTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,6 @@ public void internalIdUsage() {
});
}

@Test
@Disabled("TODO: how to handle repeated entities: turn to array vs. merge because it's the same?")
public void entitiesPassThroughRepeatEntity() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
i -> {
i.startRecord("1");
i.startEntity("some");
i.literal("field", "value1");
i.endEntity();
i.startEntity("some");
i.literal("field", "value2");
i.endEntity();
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("some[]");
o.get().startEntity("");
o.get().literal("field", "value1");
o.get().endEntity();
o.get().startEntity("");
o.get().literal("field", "value2");
f.apply(2).endEntity();
o.get().endRecord();
});
}

@Test
public void entitiesPassThroughRepeatNestedEntity() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
Expand Down Expand Up @@ -715,4 +688,142 @@ public void nulls() {
o.get().endRecord();
});
}

@Test
public void repeatToArray() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
i -> {
i.startRecord("1");
i.literal("name", "max");
i.literal("name", "mo");
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("name");
o.get().literal("1", "max");
o.get().literal("2", "mo");
o.get().endEntity();
o.get().endRecord();
});
}

@Test
public void accessArrayByIndex() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"upcase('name.2')"),
i -> {
i.startRecord("1");
i.literal("name", "max");
i.literal("name", "mo");
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("name");
o.get().literal("1", "max");
o.get().literal("2", "MO");
o.get().endEntity();
o.get().endRecord();
});
}

@Test
public void accessArrayByWildcard() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"upcase('name.*')"),
i -> {
i.startRecord("1");
i.literal("name", "max");
i.literal("name", "mo");
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("name");
o.get().literal("1", "MAX");
o.get().literal("2", "MO");
o.get().endEntity();
o.get().endRecord();
});
}

@Test
@Disabled("TODO: Repeated entities should become arrays, see #65")
public void repeatToArrayOfObjects() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"vacuum()"),
i -> {
i.startRecord("1");
i.startEntity("author");
i.literal("name", "max");
i.endEntity();
i.startEntity("author");
i.literal("name", "mo");
i.endEntity();
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("author");
o.get().startEntity("1");
o.get().literal("name", "max");
o.get().endEntity();
o.get().startEntity("2");
o.get().literal("name", "mo");
f.apply(2).endEntity();
o.get().endRecord();
});
}

@Test
@Disabled("TODO: Access arrays of objects by index, see #65")
public void accessArrayOfObjectsByIndex() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"upcase('author.2.name')"),
i -> {
i.startRecord("1");
i.startEntity("author");
i.literal("name", "max");
i.endEntity();
i.startEntity("author");
i.literal("name", "mo");
i.endEntity();
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("author");
o.get().startEntity("1");
o.get().literal("name", "max");
o.get().endEntity();
o.get().startEntity("2");
o.get().literal("name", "MO");
f.apply(2).endEntity();
o.get().endRecord();
});
}

@Test
@Disabled("TODO: Access arrays of objects by wildcard, see #65")
public void accessArrayOfObjectsByWildcard() {
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
"upcase('author.*.name')"),
i -> {
i.startRecord("1");
i.startEntity("author");
i.literal("name", "max");
i.endEntity();
i.startEntity("author");
i.literal("name", "mo");
i.endEntity();
i.endRecord();
}, (o, f) -> {
o.get().startRecord("1");
o.get().startEntity("author");
o.get().startEntity("1");
o.get().literal("name", "MAX");
o.get().endEntity();
o.get().startEntity("2");
o.get().literal("name", "MO");
f.apply(2).endEntity();
o.get().endRecord();
});
}
}

0 comments on commit 7b0cc12

Please sign in to comment.