org.babyfish.jimmer.sql.runtime.Readers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-sql Show documentation
Show all versions of jimmer-sql Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.sql.runtime;
import org.babyfish.jimmer.meta.*;
import org.babyfish.jimmer.sql.ast.PropExpression;
import org.babyfish.jimmer.sql.ast.Selection;
import org.babyfish.jimmer.sql.ast.embedded.AbstractTypedEmbeddedPropExpression;
import org.babyfish.jimmer.sql.ast.impl.ExpressionImplementor;
import org.babyfish.jimmer.sql.ast.impl.table.TableSelection;
import org.babyfish.jimmer.sql.ast.table.Table;
import org.babyfish.jimmer.sql.ast.table.spi.PropExpressionImplementor;
import org.babyfish.jimmer.sql.fetcher.Fetcher;
import org.babyfish.jimmer.sql.fetcher.Field;
import org.babyfish.jimmer.sql.fetcher.impl.FetcherSelection;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
class Readers {
private Readers() {}
public static Reader> createReader(JSqlClientImplementor sqlClient, List> selections) {
switch (selections.size()) {
case 1:
return createSingleReader(sqlClient, selections.get(0));
case 2:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1))
);
case 3:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2))
);
case 4:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3))
);
case 5:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3)),
createSingleReader(sqlClient, selections.get(4))
);
case 6:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3)),
createSingleReader(sqlClient, selections.get(4)),
createSingleReader(sqlClient, selections.get(5))
);
case 7:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3)),
createSingleReader(sqlClient, selections.get(4)),
createSingleReader(sqlClient, selections.get(5)),
createSingleReader(sqlClient, selections.get(6))
);
case 8:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3)),
createSingleReader(sqlClient, selections.get(4)),
createSingleReader(sqlClient, selections.get(5)),
createSingleReader(sqlClient, selections.get(6)),
createSingleReader(sqlClient, selections.get(7))
);
case 9:
return Reader.tuple(
createSingleReader(sqlClient, selections.get(0)),
createSingleReader(sqlClient, selections.get(1)),
createSingleReader(sqlClient, selections.get(2)),
createSingleReader(sqlClient, selections.get(3)),
createSingleReader(sqlClient, selections.get(4)),
createSingleReader(sqlClient, selections.get(5)),
createSingleReader(sqlClient, selections.get(6)),
createSingleReader(sqlClient, selections.get(7)),
createSingleReader(sqlClient, selections.get(8))
);
default:
throw new IllegalArgumentException("The selection count must between 1 and 9");
}
}
private static Reader> createSingleReader(JSqlClientImplementor sqlClient, Selection> selection) {
if (selection instanceof TableSelection) {
ImmutableType immutableType =
((TableSelection)selection).getImmutableType();
return sqlClient.getReader(immutableType);
}
if (selection instanceof Table>) {
ImmutableType immutableType =
((Table>)selection).getImmutableType();
return sqlClient.getReader(immutableType);
}
if (selection instanceof FetcherSelection>) {
Fetcher> fetcher = ((FetcherSelection>) selection).getFetcher();
ImmutableType type = fetcher.getImmutableType();
if (type.isEmbeddable()) {
return createDynamicEmbeddableReader(sqlClient, type, fetcher);
}
Reader> idReader = sqlClient.getReader(type.getIdProp());
Map> nonIdReaderMap = new LinkedHashMap<>();
for (Field field : fetcher.getFieldMap().values()) {
ImmutableProp prop = field.getProp();
if (!prop.isId() && (prop.hasStorage() || prop.getSqlTemplate() != null)) {
Reader> subReader =
prop.isEmbedded(EmbeddedLevel.SCALAR) ?
createDynamicEmbeddableReader(sqlClient, prop.getTargetType(), field.getChildFetcher()) :
sqlClient.getReader(prop);
if (subReader != null) {
nonIdReaderMap.put(prop, subReader);
}
}
}
return new ObjectReader(type, idReader, nonIdReaderMap);
}
ExpressionImplementor> unwrapped = AbstractTypedEmbeddedPropExpression.>unwrap(selection);
if (unwrapped instanceof PropExpression>) {
ImmutableProp prop = ((PropExpressionImplementor>) unwrapped).getProp();
if (prop.isScalar(TargetLevel.ENTITY) && !prop.isEmbedded(EmbeddedLevel.SCALAR)) {
return sqlClient.getReader(prop);
}
}
return sqlClient.getReader(unwrapped.getType());
}
private static Reader> createDynamicEmbeddableReader(JSqlClientImplementor sqlClient, ImmutableType type, Fetcher> fetcher) {
List props = new ArrayList<>(type.getProps().size());
List> readers = new ArrayList<>(type.getProps().size());
if (fetcher == null) {
for (ImmutableProp prop : type.getProps().values()) {
Reader> reader;
if (prop.isEmbedded(EmbeddedLevel.SCALAR)) {
reader = createDynamicEmbeddableReader(sqlClient, prop.getTargetType(), null);
} else if (!prop.isFormula()) {
assert prop.getSqlTemplate() == null; // SQL formula is not supported by embeddable
reader = sqlClient.getReader(prop);
} else {
reader = null;
}
if (reader != null) {
props.add(prop);
readers.add(reader);
}
}
} else {
for (Field field : fetcher.getFieldMap().values()) {
ImmutableProp prop = field.getProp();
Reader> reader;
if (prop.isEmbedded(EmbeddedLevel.SCALAR)) {
reader = createDynamicEmbeddableReader(sqlClient, prop.getTargetType(), field.getChildFetcher());
} else if (!prop.isFormula()) {
assert prop.getSqlTemplate() == null; // SQL formula is not supported by embeddable
reader = sqlClient.getReader(prop);
} else {
reader = null;
}
if (reader != null) {
props.add(prop);
readers.add(reader);
}
}
}
return new DynamicEmbeddedReader(type, props, readers);
}
}