initial commit
This commit is contained in:
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
10
.idea/.gitignore
generated
vendored
Normal file
10
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Environment-dependent path to Maven home directory
|
||||
/mavenHomeManager.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
9
.idea/dictionaries/project.xml
generated
Normal file
9
.idea/dictionaries/project.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="project">
|
||||
<words>
|
||||
<w>nitrix</w>
|
||||
<w>oxedos</w>
|
||||
<w>yubilee</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="corretto-24" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
17
pom.xml
Normal file
17
pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.cccwi</groupId>
|
||||
<artifactId>chaosdb</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>24</maven.compiler.source>
|
||||
<maven.compiler.target>24</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
19
src/main/java/de/cccwi/Attribute.java
Normal file
19
src/main/java/de/cccwi/Attribute.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package de.cccwi;
|
||||
|
||||
|
||||
public record Attribute(String name, Class<?> type) {
|
||||
|
||||
public Attribute rho(String newName) {
|
||||
return new Attribute(newName, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof Attribute other && name.equals(other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
}
|
||||
15
src/main/java/de/cccwi/Database.java
Normal file
15
src/main/java/de/cccwi/Database.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package de.cccwi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Database {
|
||||
private Map<String, Relation> tables;
|
||||
|
||||
public Database(Map<String, Relation> tables) {
|
||||
this.tables = tables;
|
||||
}
|
||||
|
||||
public Relation executeQuery(String query) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
79
src/main/java/de/cccwi/Main.java
Normal file
79
src/main/java/de/cccwi/Main.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package de.cccwi;
|
||||
|
||||
import de.cccwi.conditions.AttributeEquals;
|
||||
import de.cccwi.conditions.GreaterThan;
|
||||
import de.cccwi.conditions.ValueEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
var idColumn = new Attribute("id", String.class);
|
||||
var nameColumn = new Attribute("name", String.class);
|
||||
var ageColumn = new Attribute("age", Integer.class);
|
||||
var enabledColumn = new Attribute("enabled", Boolean.class);
|
||||
var userTable = new Relation(
|
||||
"Users",
|
||||
List.of(idColumn, nameColumn, ageColumn, enabledColumn),
|
||||
List.of(
|
||||
List.of(UUID.randomUUID().toString(), "nitrix", 31, true),
|
||||
List.of(UUID.randomUUID().toString(), "oxedos", 27, true),
|
||||
List.of(UUID.randomUUID().toString(), "yubilee", 30, false)
|
||||
)
|
||||
);
|
||||
System.out.println("Users");
|
||||
System.out.println(userTable);
|
||||
|
||||
var userIdColumn = new Attribute("userId", String.class);
|
||||
var typeColumn = new Attribute("type", String.class);
|
||||
var descriptionColumn = new Attribute("description", String.class);
|
||||
var eventTable = new Relation(
|
||||
"Events",
|
||||
List.of(idColumn, userIdColumn, typeColumn, descriptionColumn),
|
||||
List.of(
|
||||
List.of(UUID.randomUUID(), userTable.tuples().getFirst().getFirst(), "login", "user logged in"),
|
||||
List.of(UUID.randomUUID(), userTable.tuples().getFirst().getFirst(), "logout", "user logged out")
|
||||
)
|
||||
);
|
||||
System.out.println("Events");
|
||||
System.out.println(eventTable);
|
||||
|
||||
System.out.println("SELECT name, id, age AS howOld FROM Users WHERE age > 30");
|
||||
var resultTable = userTable
|
||||
.sigma(new GreaterThan(ageColumn, 30))
|
||||
.pi(List.of(nameColumn, idColumn, ageColumn))
|
||||
.rho(ageColumn.name(), "howOld");
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT name AS enabledUsers FROM Users WHERE NOT enabled");
|
||||
resultTable = userTable
|
||||
.sigma(new ValueEquals(enabledColumn, false))
|
||||
.pi(List.of(nameColumn))
|
||||
.rho(nameColumn.name(), "enabledUsers");
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT * FROM Users u1 JOIN Users u2 ON u1.id = u2.id");
|
||||
var u1 = userTable.rho("u1");
|
||||
var u2 = userTable.rho("u2");
|
||||
resultTable = u1.join(u2, new AttributeEquals(idColumn.rho("u1.id"), idColumn.rho("u2.id")));
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT * FROM Users u JOIN Events e ON u.id = e.userId");
|
||||
resultTable = userTable.rho("u")
|
||||
.join(eventTable.rho("e"), new AttributeEquals(idColumn.rho("u.id"), userIdColumn));
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT * FROM Users UNION Users");
|
||||
resultTable = userTable.union(userTable);
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT * FROM Users UNION ALL Users");
|
||||
resultTable = userTable.unionAll(userTable);
|
||||
System.out.println(resultTable);
|
||||
|
||||
System.out.println("SELECT * FROM Users - Users");
|
||||
resultTable = userTable.difference(userTable);
|
||||
System.out.println(resultTable);
|
||||
}
|
||||
}
|
||||
190
src/main/java/de/cccwi/Relation.java
Normal file
190
src/main/java/de/cccwi/Relation.java
Normal file
@@ -0,0 +1,190 @@
|
||||
package de.cccwi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public record Relation(
|
||||
String name,
|
||||
List<Attribute> attributes,
|
||||
List<List<Object>> tuples
|
||||
) {
|
||||
public Relation sigma(BiFunction<List<Attribute>, List<Object>, Boolean> condition) {
|
||||
return new Relation(
|
||||
name,
|
||||
List.copyOf(attributes),
|
||||
List.copyOf(tuples.stream().filter(t -> condition.apply(attributes, t)).toList())
|
||||
);
|
||||
}
|
||||
|
||||
public Relation pi(List<Attribute> newAttributes) {
|
||||
// find out the required indices in the correct order
|
||||
var indices = newAttributes.stream()
|
||||
.map(attributes::indexOf)
|
||||
.toList();
|
||||
|
||||
// filter and reorder the attributes of each row
|
||||
var resultTuples = tuples.stream()
|
||||
.map(t -> indices.stream().map(t::get).toList())
|
||||
.toList();
|
||||
|
||||
return new Relation(
|
||||
name,
|
||||
List.copyOf(newAttributes),
|
||||
List.copyOf(resultTuples)
|
||||
);
|
||||
}
|
||||
|
||||
public Relation rho(String newRelationName) {
|
||||
return new Relation(newRelationName, List.copyOf(attributes), List.copyOf(tuples));
|
||||
}
|
||||
|
||||
public Relation rho(String oldAttributeName, String newAttributeName) {
|
||||
return new Relation(
|
||||
name,
|
||||
List.copyOf(attributes.stream()
|
||||
.map(a -> a.name().equals(oldAttributeName) ? a.rho(newAttributeName) : a)
|
||||
.toList()),
|
||||
List.copyOf(tuples)
|
||||
);
|
||||
}
|
||||
|
||||
public Relation cross(Relation other) {
|
||||
assert !this.name.equals(other.name);
|
||||
|
||||
var resultTuples = new ArrayList<List<Object>>();
|
||||
for (var thisTuple : this.tuples) {
|
||||
for (var otherTuple : other.tuples) {
|
||||
resultTuples.add(Stream.concat(thisTuple.stream(), otherTuple.stream()).toList());
|
||||
}
|
||||
}
|
||||
|
||||
return new Relation(
|
||||
"%sX%s".formatted(name, other.name),
|
||||
List.copyOf(mergeAttributes(other)),
|
||||
List.copyOf(resultTuples)
|
||||
);
|
||||
}
|
||||
|
||||
public Relation union(Relation other) {
|
||||
assert attributes.size() == other.attributes.size();
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
assert attributes.get(i).equals(other.attributes.get(i));
|
||||
}
|
||||
|
||||
return new Relation(
|
||||
"%sU%s".formatted(name, other.name),
|
||||
List.copyOf(attributes),
|
||||
List.copyOf(Stream.concat(tuples.stream(), other.tuples.stream()).distinct().toList())
|
||||
);
|
||||
}
|
||||
|
||||
public Relation unionAll(Relation other) {
|
||||
assert attributes.size() == other.attributes.size();
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
assert attributes.get(i).equals(other.attributes.get(i));
|
||||
}
|
||||
|
||||
return new Relation(
|
||||
"%sU%s".formatted(name, other.name),
|
||||
List.copyOf(attributes),
|
||||
List.copyOf(Stream.concat(tuples.stream(), other.tuples.stream()).toList())
|
||||
);
|
||||
}
|
||||
|
||||
public Relation difference(Relation other) {
|
||||
assert attributes.size() == other.attributes.size();
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
assert attributes.get(i).equals(other.attributes.get(i));
|
||||
}
|
||||
|
||||
return new Relation(
|
||||
"%s-%s".formatted(name, other.name),
|
||||
List.copyOf(attributes),
|
||||
List.copyOf(tuples.stream()
|
||||
.filter(t -> other.tuples().stream().noneMatch(tt -> tt.equals(t)))
|
||||
.toList())
|
||||
);
|
||||
}
|
||||
|
||||
public Relation join(Relation other, BiFunction<List<Attribute>, List<Object>, Boolean> condition) {
|
||||
return cross(other).sigma(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
int colCount = attributes.size();
|
||||
|
||||
var columnWidths = new ArrayList<Integer>();
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
int maxWidth = attributes.get(col).name().length();
|
||||
for (var row : tuples) {
|
||||
String cell = String.valueOf(row.get(col));
|
||||
maxWidth = Math.max(maxWidth, cell.length());
|
||||
}
|
||||
columnWidths.add(maxWidth);
|
||||
}
|
||||
|
||||
Function<List<Object>, String> formatRow = row -> {
|
||||
StringBuilder line = new StringBuilder();
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
String cell = String.valueOf(row.get(col));
|
||||
line.append(String.format(" %-" + columnWidths.get(col) + "s ", cell));
|
||||
if (col < colCount - 1) line.append("|");
|
||||
}
|
||||
return line.toString();
|
||||
};
|
||||
|
||||
|
||||
// Header
|
||||
var sb = new StringBuilder();
|
||||
sb.append(formatRow.apply(attributes.stream().map(Attribute::name).map(a -> (Object) a).toList()));
|
||||
sb.append(System.lineSeparator());
|
||||
|
||||
// Trenner
|
||||
for (int col = 0; col < colCount; col++) {
|
||||
sb.append("─".repeat(columnWidths.get(col) + 2));
|
||||
if (col < colCount - 1) sb.append("┼");
|
||||
}
|
||||
sb.append(System.lineSeparator());
|
||||
|
||||
// Daten
|
||||
for (var row : tuples) {
|
||||
sb.append(formatRow.apply(row));
|
||||
sb.append(System.lineSeparator());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<Attribute> mergeAttributes(Relation other) {
|
||||
var thisAttributeName = this.attributes.stream()
|
||||
.map(Attribute::name)
|
||||
.collect(Collectors.toSet());
|
||||
var otherAttributeNames = other.attributes.stream()
|
||||
.map(Attribute::name)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
var resultAttributes = new ArrayList<Attribute>();
|
||||
for (var thisAttribute : this.attributes) {
|
||||
if (otherAttributeNames.contains(thisAttribute.name())) {
|
||||
resultAttributes.add(thisAttribute.rho("%s.%s".formatted(this.name, thisAttribute.name())));
|
||||
} else {
|
||||
resultAttributes.add(thisAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
for (var otherAttribute : other.attributes) {
|
||||
if (thisAttributeName.contains(otherAttribute.name())) {
|
||||
resultAttributes.add(otherAttribute.rho("%s.%s".formatted(other.name, otherAttribute.name())));
|
||||
} else {
|
||||
resultAttributes.add(otherAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
return resultAttributes;
|
||||
}
|
||||
}
|
||||
22
src/main/java/de/cccwi/conditions/AttributeEquals.java
Normal file
22
src/main/java/de/cccwi/conditions/AttributeEquals.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class AttributeEquals implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute lhs;
|
||||
private final Attribute rhs;
|
||||
|
||||
public AttributeEquals(Attribute lhs, Attribute rhs) {
|
||||
assert lhs.type().equals(rhs.type());
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
return rows.get(attributes.indexOf(lhs)).equals(rows.get(attributes.indexOf(rhs)));
|
||||
}
|
||||
}
|
||||
23
src/main/java/de/cccwi/conditions/GreaterThan.java
Normal file
23
src/main/java/de/cccwi/conditions/GreaterThan.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class GreaterThan implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute attribute;
|
||||
private final Integer value;
|
||||
|
||||
public GreaterThan(Attribute attribute, Integer value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
var columnIndex = attributes.indexOf(attribute);
|
||||
assert attributes.get(columnIndex).type().equals(Integer.class);
|
||||
return ((Integer) rows.get(columnIndex)) > value;
|
||||
}
|
||||
}
|
||||
23
src/main/java/de/cccwi/conditions/GreaterThanEquals.java
Normal file
23
src/main/java/de/cccwi/conditions/GreaterThanEquals.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class GreaterThanEquals implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute attribute;
|
||||
private final Integer value;
|
||||
|
||||
public GreaterThanEquals(Attribute attribute, Integer value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
var columnIndex = attributes.indexOf(attribute);
|
||||
assert attributes.get(columnIndex).type().equals(Integer.class);
|
||||
return ((Integer) rows.get(columnIndex)) >= value;
|
||||
}
|
||||
}
|
||||
23
src/main/java/de/cccwi/conditions/LessThan.java
Normal file
23
src/main/java/de/cccwi/conditions/LessThan.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class LessThan implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute attribute;
|
||||
private final Integer value;
|
||||
|
||||
public LessThan(Attribute attribute, Integer value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
var columnIndex = attributes.indexOf(attribute);
|
||||
assert attributes.get(columnIndex).type().equals(Integer.class);
|
||||
return ((Integer) rows.get(columnIndex)) < value;
|
||||
}
|
||||
}
|
||||
23
src/main/java/de/cccwi/conditions/LessThanEquals.java
Normal file
23
src/main/java/de/cccwi/conditions/LessThanEquals.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class LessThanEquals implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute attribute;
|
||||
private final Integer value;
|
||||
|
||||
public LessThanEquals(Attribute attribute, Integer value) {
|
||||
this.attribute = attribute;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
var columnIndex = attributes.indexOf(attribute);
|
||||
assert attributes.get(columnIndex).type().equals(Integer.class);
|
||||
return ((Integer) rows.get(columnIndex)) <= value;
|
||||
}
|
||||
}
|
||||
19
src/main/java/de/cccwi/conditions/Not.java
Normal file
19
src/main/java/de/cccwi/conditions/Not.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class Not implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private BiFunction<List<Attribute>, List<Object>, Boolean> condition;
|
||||
|
||||
public Not(BiFunction<List<Attribute>, List<Object>, Boolean> condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> objects) {
|
||||
return !condition.apply(attributes, objects);
|
||||
}
|
||||
}
|
||||
22
src/main/java/de/cccwi/conditions/ValueEquals.java
Normal file
22
src/main/java/de/cccwi/conditions/ValueEquals.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package de.cccwi.conditions;
|
||||
|
||||
import de.cccwi.Attribute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class ValueEquals implements BiFunction<List<Attribute>, List<Object>, Boolean> {
|
||||
private final Attribute lhs;
|
||||
private final Object rhs;
|
||||
|
||||
public ValueEquals(Attribute lhs, Object rhs) {
|
||||
assert lhs.type().isInstance(rhs);
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean apply(List<Attribute> attributes, List<Object> rows) {
|
||||
return rows.get(attributes.indexOf(lhs)).equals(rhs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user