All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.babyfish.jimmer.sql.runtime.Readers Maven / Gradle / Ivy

There is a newer version: 0.9.19
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy