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}