001package gudusoft.gsqlparser.catalog.input.model;
002
003import java.util.ArrayList;
004import java.util.Collections;
005import java.util.List;
006import java.util.Objects;
007
008/**
009 * View entry inside a {@link SchemaModel}.
010 *
011 * <p>Plan ยง6. {@link #materialized()} distinguishes materialized views from
012 * regular views; {@link #definition()} is the view body, optional in adapters
013 * that surface only metadata.</p>
014 */
015public final class ViewModel {
016
017    private final String name;
018    private final String definition;
019    private final List<ColumnModel> columns;
020    private final boolean materialized;
021
022    private ViewModel(Builder b) {
023        if (b.name == null || b.name.isEmpty()) {
024            throw new IllegalArgumentException("ViewModel.name is required");
025        }
026        this.name = b.name;
027        this.definition = b.definition;
028        this.columns = Collections.unmodifiableList(new ArrayList<ColumnModel>(b.columns));
029        this.materialized = b.materialized;
030    }
031
032    public static Builder builder() {
033        return new Builder();
034    }
035
036    public String name() {
037        return name;
038    }
039
040    /** View body text (CREATE VIEW ... AS SELECT ...). May be {@code null}. */
041    public String definition() {
042        return definition;
043    }
044
045    public List<ColumnModel> columns() {
046        return columns;
047    }
048
049    public boolean materialized() {
050        return materialized;
051    }
052
053    @Override
054    public boolean equals(Object o) {
055        if (this == o) return true;
056        if (!(o instanceof ViewModel)) return false;
057        ViewModel that = (ViewModel) o;
058        return materialized == that.materialized
059            && name.equals(that.name)
060            && Objects.equals(definition, that.definition)
061            && columns.equals(that.columns);
062    }
063
064    @Override
065    public int hashCode() {
066        return Objects.hash(name, definition, columns, materialized);
067    }
068
069    @Override
070    public String toString() {
071        return "ViewModel{name=" + name
072            + ", materialized=" + materialized
073            + ", columns=" + columns.size() + '}';
074    }
075
076    public static final class Builder {
077
078        private String name;
079        private String definition;
080        private final List<ColumnModel> columns = new ArrayList<ColumnModel>();
081        private boolean materialized;
082
083        private Builder() {
084        }
085
086        public Builder name(String v) {
087            this.name = v;
088            return this;
089        }
090
091        public Builder definition(String v) {
092            this.definition = v;
093            return this;
094        }
095
096        public Builder addColumn(ColumnModel v) {
097            if (v == null) {
098                throw new IllegalArgumentException("ViewModel column may not be null");
099            }
100            this.columns.add(v);
101            return this;
102        }
103
104        public Builder materialized(boolean v) {
105            this.materialized = v;
106            return this;
107        }
108
109        public ViewModel build() {
110            return new ViewModel(this);
111        }
112    }
113}