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}