001package gudusoft.gsqlparser; 002 003import java.util.concurrent.ConcurrentHashMap; 004 005public class TSingletonParser { 006 private static volatile TSingletonParser instance; 007 008 // Per-vendor parser cache to avoid cross-vendor contamination 009 private final ConcurrentHashMap<EDbVendor, TGSqlParser> parsers = new ConcurrentHashMap<>(); 010 011 private TSingletonParser(){} 012 013 public static TSingletonParser getInstance() { 014 015 if (instance == null) { 016 synchronized (TSingletonParser.class) { 017 if (instance == null) 018 instance = new TSingletonParser(); 019 } 020 } 021 return instance; 022 } 023 024 public synchronized TStatementList getStmts(EDbVendor dbVendor, String str){ 025 TStatementList statements = new TStatementList(); 026 TGSqlParser sqlParser = this.getParser(dbVendor); 027 sqlParser.sqltext = str; 028 int i = sqlParser.parse(); 029 if (i == 0){ 030 for(int j=0;j<sqlParser.getSqlstatements().size();j++){ 031 statements.add(sqlParser.getSqlstatements().get(j)); 032 } 033 } 034 return statements; 035 } 036 037 public synchronized TSourceTokenList getTokens(EDbVendor dbVendor, String str){ 038 TSourceTokenList stList = new TSourceTokenList(); 039 TGSqlParser sqlParser = this.getParser(dbVendor); 040 sqlParser.sqltext = str; 041 sqlParser.tokenizeSqltext(); 042 // A refusal (e.g. the trial size cap) is reported only via the error 043 // message; an empty list would be indistinguishable from "no tokens". 044 if (TBaseType.isTrialSizeMessage(sqlParser.getErrormessage())) { 045 throw new IllegalStateException(sqlParser.getErrormessage()); 046 } 047 for(int i=0;i<sqlParser.sourcetokenlist.size();i++){ 048 stList.add(sqlParser.sourcetokenlist.get(i)); 049 } 050 return stList; 051 } 052 053 private synchronized TGSqlParser getParser(EDbVendor dbVendor) { 054 return parsers.computeIfAbsent(dbVendor, TGSqlParser::new); 055 } 056 057}