001 002package gudusoft.gsqlparser.util; 003 004import gudusoft.gsqlparser.EDbVendor; 005import gudusoft.gsqlparser.util.json.JSON; 006 007import java.util.*; 008 009public class functionChecker 010{ 011 // Lazily initialized, immutable after publish; volatile for safe publication 012 private static volatile Set<String> oraclePredefinedPackageFunctionSet = null; 013 private static final Object ORACLE_INIT_LOCK = new Object(); 014 015 private static final String COMMA = ","; 016 private static final String MINUS = "-"; 017 018 private functionChecker( ) 019 { 020 } 021 022 public static boolean isOraclePredefinedPackageFunction(String inputString) { 023 if (SQLUtil.isEmpty(inputString)) { 024 return false; 025 } 026 027 // Fast path if already initialized 028 Set<String> cache = oraclePredefinedPackageFunctionSet; 029 if (cache == null) { 030 synchronized (ORACLE_INIT_LOCK) { 031 cache = oraclePredefinedPackageFunctionSet; 032 if (cache == null) { 033 // Build locally, then publish immutably to avoid further synchronization 034 Set<String> local = new HashSet<>(); 035 Object parsed = JSON.parseObject( 036 SQLUtil.getInputStreamContent( 037 functionChecker.class.getResourceAsStream("/gudusoft/gsqlparser/oracle/package/predefined.json"), 038 false)); 039 if (parsed instanceof Map) { 040 Map<?, ?> jsonObject = (Map<?, ?>) parsed; 041 for (Map.Entry<?, ?> entry : jsonObject.entrySet()) { 042 String key = String.valueOf(entry.getKey()); 043 Object value = entry.getValue(); 044 if (value instanceof List) { 045 for (Object item : (List<?>) value) { 046 local.add((key + "." + String.valueOf(item)).toUpperCase(java.util.Locale.ROOT)); 047 } 048 } 049 } 050 } 051 cache = java.util.Collections.unmodifiableSet(local); 052 oraclePredefinedPackageFunctionSet = cache; // volatile publish 053 } 054 } 055 } 056 057 return cache.contains(inputString.toUpperCase(java.util.Locale.ROOT)); 058 } 059 060 public static boolean isBuiltInFunction( String inputString, 061 EDbVendor dbvendor, String dbVersion ) 062 { 063 if ( inputString == null || inputString.trim( ).equals( "" ) ) 064 return false; 065 066 // Locale.ROOT: default-locale toUpperCase turns "td_friday" into 067 // "TD_FRİDAY" on Turkish JVMs, silently missing the list entry 068 String function = inputString.toUpperCase( java.util.Locale.ROOT ); 069 070 functionList functionList = functionListFactory.getInstance( ) 071 .getBuiltInFunctionList( dbvendor, dbVersion ); 072 if ( functionList == null ) 073 { 074 throw new IllegalArgumentException( "Can't get available built-in function list" ); 075 } 076 077 return functionList.getBuiltInFunctionList( ).contains( function ); 078 } 079 080 public static String getBuiltInFunctionList(EDbVendor dbvendor, 081 String dbVersion) { 082 functionList functionList = functionListFactory.getInstance() 083 .getBuiltInFunctionList(dbvendor, dbVersion); 084 if (functionList == null) { 085 throw new IllegalArgumentException("Can't get available built-in function list"); 086 } 087 088 Set<String> functions = functionList.getBuiltInFunctionList(); 089 090 if (functions != null) { 091 return String.join(COMMA, functions); 092 } 093 return null; 094 } 095 096 public static String compareBuiltInFunctionList( EDbVendor dbvendor1, 097 String dbVersion1, EDbVendor dbvendor2, String dbVersion2 ) 098 { 099 functionList functionList1 = functionListFactory.getInstance( ) 100 .getBuiltInFunctionList( dbvendor1, dbVersion1 ); 101 functionList functionList2 = functionListFactory.getInstance( ) 102 .getBuiltInFunctionList( dbvendor2, dbVersion2 ); 103 104 if ( functionList1 == null || functionList2 == null ) 105 { 106 throw new IllegalArgumentException( "Can't get available built-in function list" ); 107 } 108 109 List<String> list1 = new ArrayList<String>( ); 110 List<String> list2 = new ArrayList<String>( ); 111 List<String> retainList = new ArrayList<String>( ); 112 113 retainList.addAll( functionList1.getBuiltInFunctionList( ) ); 114 retainList.retainAll( functionList2.getBuiltInFunctionList( ) ); 115 list1.addAll( functionList1.getBuiltInFunctionList( ) ); 116 list2.addAll( functionList2.getBuiltInFunctionList( ) ); 117 118 list1.removeAll( retainList ); 119 list2.removeAll( retainList ); 120 121 for ( int i = 0; i < list2.size( ); i++ ) 122 { 123 list1.add( MINUS + list2.get( i ) ); 124 } 125 126 Collections.sort( list1, new Comparator<String>( ) { 127 128 public int compare( String str1, String str2 ) 129 { 130 if ( !str1.startsWith( MINUS ) ) 131 str1 = MINUS + str1; 132 if ( !str2.startsWith( MINUS ) ) 133 str2 = MINUS + str2; 134 return str1.compareToIgnoreCase( str2 ); 135 } 136 137 } ); 138 139 StringBuffer buffer = new StringBuffer( ); 140 for ( int i = 0; i < list1.size( ); i++ ) 141 { 142 buffer.append( list1.get( i ) ); 143 if ( i < list1.size( ) - 1 ) 144 buffer.append( COMMA ); 145 } 146 return buffer.toString( ); 147 } 148 149 public static List<String> getAvailableDbVersions( EDbVendor dbvendor ) 150 { 151 return functionListFactory.getInstance( ) 152 .getAvailableDbVersions( dbvendor ); 153 } 154 155 public static boolean containsDbVersion( EDbVendor dbvendor, 156 String dbVersion ) 157 { 158 return functionListFactory.getInstance( ).containsDbVersion( dbvendor, 159 dbVersion ); 160 } 161 162 public static void main(String[] args) { 163 System.out.println(functionChecker.getBuiltInFunctionList(EDbVendor.dbvoracle, "11.2")); 164 System.out.println(functionChecker.isBuiltInFunction("power", EDbVendor.dbvoracle, "11.2")); 165 long time = System.currentTimeMillis(); 166 for (int i = 0; i < 1000000; i++) { 167 functionChecker.isBuiltInFunction("power", EDbVendor.dbvoracle, "11.2"); 168 } 169 System.out.println(System.currentTimeMillis() - time); 170 } 171 172// public static void main( String[] args ){ 173// EDbVendor db = EDbVendor.dbvoracle; 174// int i = functionChecker.getAvailableDbVersions(db).size(); 175// for(int k=0;k<i;k++) { 176// System.out.println(functionChecker.getAvailableDbVersions(db).get(k)); 177// } 178// System.out.println(functionChecker.isOraclePredefinedPackageFunction("DBMS_RANDOM.RANDOM")); 179// } 180 181}