001package gudusoft.gsqlparser;
002
003import java.util.ArrayList;
004import java.util.Arrays;
005import java.util.HashMap;
006import java.util.List;
007import java.util.Map;
008
009/**
010 * Database vendors known to the parser API.
011 *
012 * <p>Use {@link #isImplemented()} to inspect Java implementation status rather
013 * than maintaining a separate vendor list. Public product metadata, aliases,
014 * samples, runtime support, and surface publication state live in
015 * {@code dialects/v2/manifest.json}.</p>
016 *
017 * <p>There is no specific Microsoft Access engine ({@link #dbvaccess}); use
018 * {@link #dbvmssql} where that compatibility is appropriate.</p>
019 */
020public enum EDbVendor {
021    dbvaccess(new String[]{"access"}, "Microsoft Access", 0),
022    dbvansi(new String[]{"ansi"}, "ANSI SQL", 0),
023    dbvathena(new String[]{"athena"}, "AWS Athena", 1), //aws,2021/9/18
024    dbvazuresql(new String[]{"azuresql", "azure"}, "Azure SQL", 1),
025    dbvbigquery(new String[]{"bigquery"}, "Google BigQuery", 1),
026    dbvclickhouse(new String[]{"clickhouse"}, "ClickHouse", 1),
027    dbvcouchbase(new String[]{"couchbase"}, "Couchbase", 1),
028    dbvdax(new String[]{"dax"}, "Microsoft DAX", 0),
029    dbvdb2(new String[]{"db2"}, "IBM DB2", 1),
030    dbvdoris(new String[]{"doris"}, "Apache Doris", 1),
031    dbvduckdb(new String[]{"duckdb"}, "DuckDB", 1),
032    dbvexasol(new String[]{"exasol"}, "Exasol", 0),
033    dbvfirebird(new String[]{"firebird"}, "Firebird", 0),
034    dbvflink(new String[]{"flink"}, "Apache Flink SQL", 1),
035    dbvgeneric(new String[]{"generic"}, "Generic SQL", 0),
036    dbvgreenplum(new String[]{"greenplum"}, "Greenplum", 1),
037    dbvhana(new String[]{"hana"}, "SAP HANA", 1),
038    dbvhive(new String[]{"hive"}, "Apache Hive", 1),
039    dbvimpala(new String[]{"impala"}, "Apache Impala", 1),
040    dbvinformix(new String[]{"informix"}, "IBM Informix", 1),
041    dbvmdx(new String[]{"mdx"}, "MDX", 1),
042    dbvmysql(new String[]{"mysql"}, "MySQL", 1),
043    dbvmssql(new String[]{"mssql", "sqlserver"}, "Microsoft SQL Server", 1),
044    dbvnetezza(new String[]{"netezza"}, "IBM Netezza", 1),
045    dbvodbc(new String[]{"odbc"}, "ODBC", 1),
046    dbvopenedge(new String[]{"openedge"}, "Progress OpenEdge", 1),
047    dbvoracle(new String[]{"oracle"}, "Oracle", 1),
048    dbvpostgresql(new String[]{"postgresql", "postgres"}, "PostgreSQL", 1),
049    dbvpowerquery(new String[]{"powerquery", "m", "powerbi"}, "Power Query M Language", 1), //2026/4/19 — Tier1 NativeQuery, Tier2 nav chain
050    dbvpresto(new String[]{"presto"}, "Presto", 1), //2021/9/18
051    dbvredshift(new String[]{"redshift"}, "Amazon Redshift", 1),
052    dbvsnowflake(new String[]{"snowflake"}, "Snowflake", 1),
053    dbvsoql(new String[]{"soql"}, "Salesforce SOQL", 1),
054    dbvsparksql(new String[]{"sparksql", "spark"}, "Apache Spark SQL", 1),
055    dbvsqlite(new String[]{"sqlite"}, "SQLite", 1),
056    dbvstarrocks(new String[]{"starrocks"}, "StarRocks", 1),
057    dbvsybase(new String[]{"sybase"}, "Sybase", 1),
058    dbvteradata(new String[]{"teradata"}, "Teradata", 1),
059    dbvtrino(new String[]{"trino"}, "Trino", 1), //2021/9/18
060    dbvvertica(new String[]{"vertica"}, "Vertica", 1),
061    dbvdatabricks(new String[]{"databricks"}, "Databricks", 1), //2022/10/30
062    dbvgaussdb(new String[]{"gaussdb"}, "GaussDB", 1), //2023/9/28
063    dbvedb(new String[]{"edb", "epas"}, "EDB Postgres Advanced Server", 1), //2026/3/18
064    dbvdameng(new String[]{"dameng", "dm"}, "Dameng Database", 1), //2026/4/10
065    dbvoceanbase(new String[]{"oceanbase", "ob"}, "OceanBase", 1), //2026/4/11 — Phase 3 landed: dual-fork active (oceanbasemysql/ + oceanbaseoracle/), status=1 (publicly visible)
066    // Sybase family decomposition (2026/8/16). APPENDED AT THE TAIL, not
067    // alphabetically: enum ordinals shift for every later constant when a value
068    // is inserted mid-list, and external integrations may persist ordinals.
069    // Appending is the standing repo convention (dbvdatabricks..dbvoceanbase).
070    dbvsybasease(new String[]{"sybasease", "ase"}, "Sybase ASE", 1),
071    dbvsqlanywhere(new String[]{"sqlanywhere", "asa"}, "SAP SQL Anywhere", 1),
072    dbvsybaseiq(new String[]{"sybaseiq", "iq"}, "Sybase IQ", 1);
073
074    private final String[] aliases;
075    private final String description;
076    private final int status; // 0 means not implemented, 1 means implemented
077    private static final Map<String, EDbVendor> aliasMap = new HashMap<>();
078
079    static {
080        for (EDbVendor vendor : values()) {
081            for (String alias : vendor.aliases) {
082                aliasMap.put(alias.toLowerCase(), vendor);
083            }
084        }
085    }
086
087    EDbVendor(String[] aliases, String description, int status) {
088        this.aliases = aliases;
089        this.description = description;
090        this.status = status;
091    }
092
093    /**
094     * Get the primary string representation of this database vendor
095     * @return the primary alias (first in the list)
096     */
097    public String getPrimaryAlias() {
098        return aliases[0];
099    }
100
101    /**
102     * Get all string representations of this database vendor
103     * @return array of all aliases
104     */
105    public String[] getAliases() {
106        return aliases;
107    }
108
109    /**
110     * Get the description of this database vendor
111     * @return the description
112     */
113    public String getDescription() {
114        return description;
115    }
116    
117    /**
118     * Get the implementation status of this database vendor
119     * @return 0 for not implemented, 1 for implemented
120     */
121    public int getStatus() {
122        return status;
123    }
124    
125    /**
126     * Check if this database vendor is implemented
127     * @return true if implemented, false otherwise
128     */
129    public boolean isImplemented() {
130        return status == 1;
131    }
132
133    /**
134     * Get the database vendor from a string representation
135     * @param alias the string representation
136     * @return the corresponding database vendor or null if not found
137     */
138    public static EDbVendor fromAlias(String alias) {
139        if (alias == null) {
140            return null;
141        }
142        return aliasMap.get(alias.toLowerCase());
143    }
144
145    /**
146     * Get the database vendor from a string representation, returning dbvoracle as default if not found
147     * @param alias the string representation
148     * @return the corresponding database vendor or dbvoracle if not found
149     */
150    public static EDbVendor valueOfWithDefault(String alias) {
151        EDbVendor vendor = fromAlias(alias);
152        return vendor != null ? vendor : dbvoracle;
153    }
154
155    /**
156     * Returns an array of strings representing all database vendors
157     * using their primary aliases (first alias), sorted alphabetically
158     * @return array of all primary database vendor aliases
159     */
160    public static String[] getAllVendorAliases() {
161        return getAllVendorAliases(false);
162    }
163    
164    /**
165     * Returns an array of strings representing database vendors
166     * using their primary aliases (first alias), sorted alphabetically
167     * @param implementedOnly if true, only implemented vendors are included
168     * @return array of primary database vendor aliases
169     */
170    public static String[] getAllVendorAliases(boolean implementedOnly) {
171        EDbVendor[] allVendors = values();
172        List<String> aliasList = new ArrayList<>();
173        
174        for (EDbVendor vendor : allVendors) {
175            if (!implementedOnly || vendor.isImplemented()) {
176                aliasList.add(vendor.getPrimaryAlias());
177            }
178        }
179        
180        String[] aliases = aliasList.toArray(new String[0]);
181        Arrays.sort(aliases);
182        return aliases;
183    }
184
185    /**
186     * Check if a string representation corresponds to this database vendor
187     * @param alias the string to check
188     * @return true if the string represents this vendor, false otherwise
189     */
190    public boolean matchesAlias(String alias) {
191        if (alias == null) {
192            return false;
193        }
194        return Arrays.asList(getAliases()).contains(alias.toLowerCase());
195    }
196}