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 String function = inputString.toUpperCase( ); 067 068 functionList functionList = functionListFactory.getInstance( ) 069 .getBuiltInFunctionList( dbvendor, dbVersion ); 070 if ( functionList == null ) 071 { 072 throw new IllegalArgumentException( "Can't get available built-in function list" ); 073 } 074 075 return functionList.getBuiltInFunctionList( ).contains( function ); 076 } 077 078 public static String getBuiltInFunctionList(EDbVendor dbvendor, 079 String dbVersion) { 080 functionList functionList = functionListFactory.getInstance() 081 .getBuiltInFunctionList(dbvendor, dbVersion); 082 if (functionList == null) { 083 throw new IllegalArgumentException("Can't get available built-in function list"); 084 } 085 086 Set<String> functions = functionList.getBuiltInFunctionList(); 087 088 if (functions != null) { 089 return String.join(COMMA, functions); 090 } 091 return null; 092 } 093 094 public static String compareBuiltInFunctionList( EDbVendor dbvendor1, 095 String dbVersion1, EDbVendor dbvendor2, String dbVersion2 ) 096 { 097 functionList functionList1 = functionListFactory.getInstance( ) 098 .getBuiltInFunctionList( dbvendor1, dbVersion1 ); 099 functionList functionList2 = functionListFactory.getInstance( ) 100 .getBuiltInFunctionList( dbvendor2, dbVersion2 ); 101 102 if ( functionList1 == null || functionList2 == null ) 103 { 104 throw new IllegalArgumentException( "Can't get available built-in function list" ); 105 } 106 107 List<String> list1 = new ArrayList<String>( ); 108 List<String> list2 = new ArrayList<String>( ); 109 List<String> retainList = new ArrayList<String>( ); 110 111 retainList.addAll( functionList1.getBuiltInFunctionList( ) ); 112 retainList.retainAll( functionList2.getBuiltInFunctionList( ) ); 113 list1.addAll( functionList1.getBuiltInFunctionList( ) ); 114 list2.addAll( functionList2.getBuiltInFunctionList( ) ); 115 116 list1.removeAll( retainList ); 117 list2.removeAll( retainList ); 118 119 for ( int i = 0; i < list2.size( ); i++ ) 120 { 121 list1.add( MINUS + list2.get( i ) ); 122 } 123 124 Collections.sort( list1, new Comparator<String>( ) { 125 126 public int compare( String str1, String str2 ) 127 { 128 if ( !str1.startsWith( MINUS ) ) 129 str1 = MINUS + str1; 130 if ( !str2.startsWith( MINUS ) ) 131 str2 = MINUS + str2; 132 return str1.compareToIgnoreCase( str2 ); 133 } 134 135 } ); 136 137 StringBuffer buffer = new StringBuffer( ); 138 for ( int i = 0; i < list1.size( ); i++ ) 139 { 140 buffer.append( list1.get( i ) ); 141 if ( i < list1.size( ) - 1 ) 142 buffer.append( COMMA ); 143 } 144 return buffer.toString( ); 145 } 146 147 public static List<String> getAvailableDbVersions( EDbVendor dbvendor ) 148 { 149 return functionListFactory.getInstance( ) 150 .getAvailableDbVersions( dbvendor ); 151 } 152 153 public static boolean containsDbVersion( EDbVendor dbvendor, 154 String dbVersion ) 155 { 156 return functionListFactory.getInstance( ).containsDbVersion( dbvendor, 157 dbVersion ); 158 } 159 160 public static void main(String[] args) { 161 System.out.println(functionChecker.getBuiltInFunctionList(EDbVendor.dbvoracle, "11.2")); 162 System.out.println(functionChecker.isBuiltInFunction("power", EDbVendor.dbvoracle, "11.2")); 163 long time = System.currentTimeMillis(); 164 for (int i = 0; i < 1000000; i++) { 165 functionChecker.isBuiltInFunction("power", EDbVendor.dbvoracle, "11.2"); 166 } 167 System.out.println(System.currentTimeMillis() - time); 168 } 169 170// public static void main( String[] args ){ 171// EDbVendor db = EDbVendor.dbvoracle; 172// int i = functionChecker.getAvailableDbVersions(db).size(); 173// for(int k=0;k<i;k++) { 174// System.out.println(functionChecker.getAvailableDbVersions(db).get(k)); 175// } 176// System.out.println(functionChecker.isOraclePredefinedPackageFunction("DBMS_RANDOM.RANDOM")); 177// } 178 179}