001package gudusoft.gsqlparser.pp2.dialect;
002
003import gudusoft.gsqlparser.EDbVendor;
004
005import java.util.concurrent.ConcurrentHashMap;
006
007/**
008 * Maps an {@link EDbVendor} to its {@link DialectStrategy}. Vendors with a
009 * dedicated strategy (Oracle, MSSQL, MySQL, DB2, Snowflake) get it; every other
010 * vendor gets a {@link GenericDialect} for that vendor. Results are memoised per
011 * vendor so {@code forVendor} is cheap and the returned strategy is stable.
012 *
013 * <p>This is the single place pp2 branches on vendor: the layout rules consult
014 * the strategy rather than switching on {@code EDbVendor} themselves.
015 *
016 * <p>Plan reference: §7.3/S30, §7.4/S30.
017 */
018public final class DialectRegistry {
019
020    private static final ConcurrentHashMap<EDbVendor, DialectStrategy> CACHE =
021        new ConcurrentHashMap<EDbVendor, DialectStrategy>();
022
023    private DialectRegistry() { }
024
025    /**
026     * The strategy for {@code vendor}; never null. Dedicated strategies exist
027     * for Oracle/MSSQL/MySQL/DB2/Snowflake; all other vendors get a
028     * {@link GenericDialect}.
029     *
030     * @throws NullPointerException if {@code vendor} is null
031     */
032    public static DialectStrategy forVendor(final EDbVendor vendor) {
033        if (vendor == null) throw new NullPointerException("vendor");
034        DialectStrategy cached = CACHE.get(vendor);
035        if (cached != null) return cached;
036        return CACHE.computeIfAbsent(vendor, new java.util.function.Function<EDbVendor, DialectStrategy>() {
037            @Override
038            public DialectStrategy apply(EDbVendor v) {
039                return create(v);
040            }
041        });
042    }
043
044    private static DialectStrategy create(EDbVendor vendor) {
045        switch (vendor) {
046            case dbvoracle:    return new OracleDialect();
047            case dbvmssql:     return new MssqlDialect();
048            case dbvmysql:     return new MysqlDialect();
049            case dbvdb2:       return new Db2Dialect();
050            case dbvsnowflake: return new SnowflakeDialect();
051            default:           return new GenericDialect(vendor);
052        }
053    }
054}