Skip to content

Commit

Permalink
Merge pull request #2 from erupts/dev
Browse files Browse the repository at this point in the history
0.0.4
  • Loading branch information
erupts authored Apr 11, 2024
2 parents 071078d + 37595bf commit 2a88351
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 128 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>linq.j</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
</dependency>
```

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

<groupId>xyz.erupt</groupId>
<artifactId>linq.j</artifactId>
<version>0.0.3</version>
<version>0.0.4</version>
<name>Linq.j</name>

<description>Linq.J A JVM → Lambda based federated analysis library</description>
<description>Linq.J in Java , Lambda Language Integrated Query library</description>
<url>https://github.com/erupts/Linq.J</url>

<properties>
Expand Down
21 changes: 16 additions & 5 deletions src/main/java/xyz/erupt/linq/Linq.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public Linq() {

private final Dql dql = new Dql();


public static Linq from(Collection<?> data) {
Linq linq = new Linq();
linq.dql.setFrom(data);
Expand Down Expand Up @@ -80,16 +79,28 @@ public Linq distinct() {
}

@Override
public Linq select(Column column, Column... columns) {
this.dql.getColumns().addAll(Columns.columnsUnfold(column));
public Linq select(Column... columns) {
this.dql.getColumns().addAll(Columns.columnsUnfold(columns));
return this;
}

@SafeVarargs
@Override
public final <T> Linq selectExclude(SFunction<T, ?>... columns) {
this.dql.getColumns().removeIf(it -> {
for (SFunction<T, ?> column : columns) {
if (Columns.of(column).equals(it)) {
return true;
}
}
return false;
});
return this;
}

@Override
@SafeVarargs
public final <T> Linq select(SFunction<T, ?> column, SFunction<T, ?>... columns) {
this.dql.getColumns().add(Columns.of(column));
public final <T> Linq select(SFunction<T, ?>... columns) {
for (SFunction<T, ?> col : columns) {
this.dql.getColumns().add(Columns.of(col));
}
Expand Down
105 changes: 55 additions & 50 deletions src/main/java/xyz/erupt/linq/engine/EruptEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import xyz.erupt.linq.consts.OrderByDirection;
import xyz.erupt.linq.exception.LinqException;
import xyz.erupt.linq.schema.*;
import xyz.erupt.linq.util.ColumnReflects;
import xyz.erupt.linq.util.RowUtil;
import xyz.erupt.linq.util.Columns;

import java.util.*;
Expand All @@ -15,40 +15,13 @@ public class EruptEngine extends Engine {

@Override
public List<Row> query(Dql dql) {
List<Row> dataset = ColumnReflects.listToRow(dql.getFrom());
List<Row> dataset = RowUtil.listObjectToRow(dql.getFrom());
// join process
if (!dql.getJoinSchemas().isEmpty()) {
for (JoinSchema<?> joinSchema : dql.getJoinSchemas()) {
Column lon = Columns.of(joinSchema.getLon());
Column ron = Columns.of(joinSchema.getRon());
if (joinSchema.getJoinExchange() == JoinExchange.HASH) {
List<Row> targetData = ColumnReflects.listToRow(joinSchema.getTarget());
switch (joinSchema.getJoinMethod()) {
case LEFT:
this.crossHashJoin(dataset, ron, targetData, lon);
break;
case RIGHT:
this.crossHashJoin(targetData, lon, dataset, ron);
dataset = targetData;
break;
case INNER:
this.crossHashJoin(dataset, ron, targetData, lon);
dataset.removeIf(it -> !it.containsKey(lon));
break;
case FULL:
this.crossHashJoin(dataset, ron, targetData, lon);
this.crossHashJoin(targetData, lon, dataset, ron);
targetData.removeIf(it -> it.containsKey(ron));
dataset.addAll(targetData);
break;
}
} else {
throw new LinqException(joinSchema.getJoinExchange().name() + " is not supported yet");
}
}
this.join(dql, dataset);
}
// condition process
if (!dql.getWheres().isEmpty()){
// where process
if (!dql.getWheres().isEmpty()) {
dataset.removeIf(it -> {
for (Function<Row, Boolean> condition : dql.getWheres()) {
if (!condition.apply(it)) return true;
Expand Down Expand Up @@ -83,7 +56,7 @@ public List<Row> query(Dql dql) {
dataset.addAll($table);
}
// having process
if (!dql.getHaving().isEmpty()){
if (!dql.getHaving().isEmpty()) {
dataset.removeIf(it -> {
for (Function<Row, Boolean> condition : dql.getHaving()) {
if (!condition.apply(it)) return true;
Expand All @@ -92,7 +65,9 @@ public List<Row> query(Dql dql) {
});
}
// order by process
this.orderBy(dql, dataset);
if (!dql.getOrderBys().isEmpty()) {
this.orderBy(dql, dataset);
}
// limit
if (null != dql.getOffset()) {
dataset = dql.getOffset() > dataset.size() ? new ArrayList<>(0) : dataset.subList(dql.getOffset(), dataset.size());
Expand All @@ -107,6 +82,38 @@ public List<Row> query(Dql dql) {
return dataset;
}

public void join(Dql dql, List<Row> dataset) {
for (JoinSchema<?> joinSchema : dql.getJoinSchemas()) {
Column lon = Columns.of(joinSchema.getLon());
Column ron = Columns.of(joinSchema.getRon());
if (joinSchema.getJoinExchange() == JoinExchange.HASH) {
List<Row> targetData = RowUtil.listObjectToRow(joinSchema.getTarget());
switch (joinSchema.getJoinMethod()) {
case LEFT:
this.crossHashJoin(dataset, ron, targetData, lon);
break;
case RIGHT:
this.crossHashJoin(targetData, lon, dataset, ron);
dataset.clear();
dataset.addAll(targetData);
break;
case INNER:
this.crossHashJoin(dataset, ron, targetData, lon);
dataset.removeIf(it -> !it.containsKey(lon));
break;
case FULL:
this.crossHashJoin(dataset, ron, targetData, lon);
this.crossHashJoin(targetData, lon, dataset, ron);
targetData.removeIf(it -> it.containsKey(ron));
dataset.addAll(targetData);
break;
}
} else {
throw new LinqException(joinSchema.getJoinExchange().name() + " is not supported yet");
}
}
}

//Cartesian product case
private void crossHashJoin(List<Row> source, Column sourceColumn,
List<Row> target, Column targetColumn) {
Expand Down Expand Up @@ -171,23 +178,21 @@ public List<Row> groupBy(Dql dql, List<Row> dataset) {
}

public void orderBy(Dql dql, List<Row> dataset) {
if (null != dql.getOrderBys() && !dql.getOrderBys().isEmpty()) {
dataset.sort((a, b) -> {
int i = 0;
for (OrderBySchema orderBy : dql.getOrderBys()) {
if (null == a.get(orderBy.getColumn()) || null == b.get(orderBy.getColumn())) return 0;
if (a.get(orderBy.getColumn()) instanceof Comparable) {
Comparable<Object> comparable = (Comparable<Object>) a.get(orderBy.getColumn());
i = comparable.compareTo(b.get(orderBy.getColumn()));
if (orderBy.getDirection() == OrderByDirection.DESC) i = ~i + 1;
if (i != 0) return i;
} else {
throw new LinqException(orderBy.getColumn().getTable() + "." + orderBy.getColumn().getField() + " sort does not implement the Comparable interface");
}
dataset.sort((a, b) -> {
int i = 0;
for (OrderBySchema orderBy : dql.getOrderBys()) {
if (null == a.get(orderBy.getColumn()) || null == b.get(orderBy.getColumn())) return 0;
if (a.get(orderBy.getColumn()) instanceof Comparable) {
Comparable<Object> comparable = (Comparable<Object>) a.get(orderBy.getColumn());
i = comparable.compareTo(b.get(orderBy.getColumn()));
if (orderBy.getDirection() == OrderByDirection.DESC) i = ~i + 1;
if (i != 0) return i;
} else {
throw new LinqException(orderBy.getColumn().getTable() + "." + orderBy.getColumn().getField() + " sort does not implement the Comparable interface");
}
return i;
});
}
}
return i;
});
}

}
6 changes: 4 additions & 2 deletions src/main/java/xyz/erupt/linq/grammar/Select.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ public interface Select {

Linq distinct();

Linq select(Column column, Column... columns);
Linq select(Column... columns);

<T> Linq select(SFunction<T, ?> column, SFunction<T, ?>... columns);
<T> Linq selectExclude(SFunction<T, ?>... columns);

<T> Linq select(SFunction<T, ?>... columns);

}
6 changes: 3 additions & 3 deletions src/main/java/xyz/erupt/linq/grammar/Write.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import xyz.erupt.linq.exception.LinqException;
import xyz.erupt.linq.schema.Dql;
import xyz.erupt.linq.schema.Row;
import xyz.erupt.linq.util.ColumnReflects;
import xyz.erupt.linq.util.RowUtil;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -23,7 +23,7 @@ public interface Write {
default <T> List<T> write(Class<T> clazz) {
wEngine().preprocessor(this.wDQL());
List<Row> table = wEngine().query(this.wDQL());
return table.stream().map(it -> ColumnReflects.rowToObject(it, clazz)).collect(Collectors.toList());
return table.stream().map(it -> RowUtil.rowToObject(it, clazz)).collect(Collectors.toList());
}

default <T> T writeOne(Class<T> clazz) {
Expand All @@ -32,7 +32,7 @@ default <T> T writeOne(Class<T> clazz) {
if (result.isEmpty()) {
return null;
} else if (result.size() == 1) {
return ColumnReflects.rowToObject(result.get(0), clazz);
return RowUtil.rowToObject(result.get(0), clazz);
} else {
throw new LinqException(MULTI_VAL_ERROR + result.size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LambdaReflect {
public class LambdaSee {

private static final String GET = "get", IS = "is", WRITE_REPLACE = "writeReplace";

Expand All @@ -21,19 +21,25 @@ public static <T, R> String field(SFunction<T, R> func) {
return info(func).getField();
}

public static <T, R> String method(SFunction<T, R> func) {
return info(func).getMethod();
}

public static <T, R> LambdaInfo info(SFunction<T, R> func) {
try {
if (S_FUNCTION_CACHE.containsKey(func)) {
return S_FUNCTION_CACHE.get(func);
} else synchronized (LambdaReflect.class) {
} else synchronized (LambdaSee.class) {
if (S_FUNCTION_CACHE.containsKey(func)) return S_FUNCTION_CACHE.get(func);
}
if (!func.getClass().isSynthetic()) throw new LinqException("Synthetic classes produced by non-lambda expressions");
if (!func.getClass().isSynthetic())
throw new LinqException("Synthetic classes produced by non-lambda expressions");
Method method = func.getClass().getDeclaredMethod(WRITE_REPLACE);
method.setAccessible(true);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(func);
Matcher matcher = CLASS_TYPE_PATTERN.matcher(serializedLambda.getInstantiatedMethodType());
if (!matcher.find() || matcher.groupCount() != 1) throw new RuntimeException("Failed to get Lambda information");
if (!matcher.find() || matcher.groupCount() != 1)
throw new RuntimeException("Failed to get Lambda information");
Class<?> clazz = Class.forName(matcher.group(1).replace("/", "."));
LambdaInfo lambdaInfo = getserializedLambdaInfo(serializedLambda, clazz);
S_FUNCTION_CACHE.put(func, lambdaInfo);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/xyz/erupt/linq/schema/Column.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Column column = (Column) o;
return Objects.equals(table.getSimpleName(), column.table.getSimpleName()) && Objects.equals(field, column.field) && Objects.equals(alias, column.alias);
return Objects.equals(table.getName(), column.table.getName()) && Objects.equals(field, column.field) && Objects.equals(alias, column.alias);
}

@Override
Expand All @@ -103,7 +103,7 @@ public int hashCode() {

@Override
public String toString() {
return table.getSimpleName() + "." + field + "(" + alias + ")";
return table.getName() + "." + field + "(" + alias + ")";
}


Expand Down
6 changes: 1 addition & 5 deletions src/main/java/xyz/erupt/linq/schema/Dql.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class Dql {
private Collection<?> from;

// columns definition
private List<Column> columns = new ArrayList<>();
private final List<Column> columns = new ArrayList<>();

// json definition
private final List<JoinSchema<?>> joinSchemas = new ArrayList<>();
Expand Down Expand Up @@ -53,10 +53,6 @@ public List<Column> getColumns() {
return columns;
}

public void setColumns(List<Column> columns) {
this.columns = columns;
}

public List<Function<Row, Boolean>> getWheres() {
return wheres;
}
Expand Down
19 changes: 2 additions & 17 deletions src/main/java/xyz/erupt/linq/schema/JoinSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import xyz.erupt.linq.consts.JoinExchange;
import xyz.erupt.linq.consts.JoinMethod;
import xyz.erupt.linq.lambda.LambdaReflect;
import xyz.erupt.linq.lambda.LambdaSee;
import xyz.erupt.linq.lambda.SFunction;

import java.util.Collection;
Expand Down Expand Up @@ -31,7 +31,7 @@ public JoinSchema(JoinMethod joinMethod, Collection<T> target, SFunction<T, ?> l
this.target = target;
this.lon = lon;
this.ron = ron;
this.clazz = (Class<T>) LambdaReflect.info(lon).getClazz();
this.clazz = (Class<T>) LambdaSee.info(lon).getClazz();
this.joinExchange = JoinExchange.HASH;
}

Expand Down Expand Up @@ -59,27 +59,12 @@ public Class<T> getClazz() {
return clazz;
}

public BiFunction<T, Row, Boolean> getOn() {
return on;
}

public void setOn(BiFunction<T, Row, Boolean> on) {
this.on = on;
}

public SFunction<T, ?> getLon() {
return lon;
}

public void setLon(SFunction<T, ?> lon) {
this.lon = lon;
}

public SFunction<?, ?> getRon() {
return ron;
}

public void setRon(SFunction<?, ?> ron) {
this.ron = ron;
}
}
Loading

0 comments on commit 2a88351

Please sign in to comment.