001package gudusoft.gsqlparser.sqlenv.parser;
002
003import gudusoft.gsqlparser.EDbVendor;
004import gudusoft.gsqlparser.sqlenv.TSQLEnv;
005import gudusoft.gsqlparser.sqlenv.parser.grabit.GrabitSQLEnv;
006import gudusoft.gsqlparser.sqlenv.parser.grabit.MultipleGrabitSQLEnv;
007import gudusoft.gsqlparser.sqlenv.parser.sharded.SqlflowShardedSQLEnv;
008import gudusoft.gsqlparser.sqlenv.parser.sqldep.MultipleSQLDepSQLEnv;
009import gudusoft.gsqlparser.sqlenv.parser.sqldep.SQLDepSQLEnv;
010import gudusoft.gsqlparser.sqlenv.parser.sqlflow.SqlflowSQLEnv;
011import gudusoft.gsqlparser.util.SQLUtil;
012import gudusoft.gsqlparser.util.json.JSON;
013
014import java.io.File;
015import java.io.IOException;
016import java.nio.charset.StandardCharsets;
017import java.nio.file.Files;
018import java.nio.file.Path;
019import java.nio.file.Paths;
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023import java.util.logging.Level;
024import java.util.logging.Logger;
025
026@SuppressWarnings("rawtypes")
027public class TJSONSQLEnvParser implements TSQLEnvParser {
028        
029        private String defaultServer;
030        private String defaultDatabase;
031        private String defaultSchema;
032        
033        public TJSONSQLEnvParser(String defaultServer, String defaultDatabase, String defaultSchema) {
034                this.defaultServer = defaultServer;
035                this.defaultDatabase = defaultDatabase;
036                this.defaultSchema = defaultSchema;
037        }
038
039        public TSQLEnv[] parseSQLEnv(EDbVendor vendor, String sql) {
040                if (SQLUtil.isEmpty(sql))
041                        return null;
042
043                String trimSQL = sql.trim();
044
045                // Check if input is a file path (for sqlflow-sharded format)
046                String baseDir = null;
047                String jsonContent = trimSQL;
048
049                if (!trimSQL.startsWith("{") && !trimSQL.startsWith("[")) {
050                        // Try to interpret as a file path
051                        File file = new File(trimSQL);
052                        if (file.exists() && file.isFile()) {
053                                Path filePath = file.toPath();
054                                Path parentDir = filePath.getParent();
055                                baseDir = (parentDir != null) ? parentDir.toString() : "";
056
057                                try {
058                                        jsonContent = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8).trim();
059                                } catch (IOException e) {
060                                        Logger.getLogger(TJSONSQLEnvParser.class.getName())
061                                                        .log(Level.WARNING, "Failed to read file: " + trimSQL, e);
062                                        return null;
063                                }
064                        }
065                }
066
067                if (jsonContent.startsWith("{") && jsonContent.endsWith("}")) {
068                        return getJSONSQLEnv(vendor, jsonContent, baseDir);
069                }
070
071                if (jsonContent.startsWith("[") && jsonContent.endsWith("]")) {
072                        return getMultipleJSONSQLEnv(vendor, jsonContent);
073                }
074
075                return null;
076        }
077
078        private TSQLEnv[] getMultipleJSONSQLEnv(EDbVendor vendor, String trimSQL) {
079                try {
080                        List json = (List) JSON.parseObject(trimSQL);
081                        if (trimSQL.indexOf("createdBy") != -1) {
082                                if (trimSQL.toLowerCase().indexOf("sqldep") != -1) {
083                                        return new TSQLEnv[] { new MultipleSQLDepSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, json) };
084                                }
085                                if (trimSQL.toLowerCase().indexOf("grabit") != -1) {
086                                        return new TSQLEnv[] { new MultipleGrabitSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, json) };
087                                }
088                        }
089                } catch (Exception e) {
090                        Logger.getLogger(TJSONSQLEnvParser.class.getName()).log(Level.WARNING, "Parse json failed.", e);
091                }
092                return null;
093        }
094
095        private TSQLEnv[] getJSONSQLEnv(EDbVendor vendor, String trimSQL, String baseDir) {
096                try {
097                        Map json = (Map) JSON.parseObject(trimSQL);
098                        if (json.containsKey("createdBy")) {
099                                String createdBy = (String) json.get("createdBy");
100                                if (createdBy.toLowerCase().indexOf("sqldep") != -1) {
101                                        return new TSQLEnv[] { new SQLDepSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, json) };
102                                }
103                                if (createdBy.toLowerCase().indexOf("grabit") != -1) {
104                                        return new TSQLEnv[] { new GrabitSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, json) };
105                                }
106                                if (createdBy.toLowerCase().indexOf("sqlflow") != -1) {
107                                        if(json.containsKey("format") && json.get("format").toString().equals("sqlflow-sharded")){
108                                                List servers = (List) json.get("servers");
109                                                if (servers == null)
110                                                        return null;
111                                                List<TSQLEnv> sqlEnvs = new ArrayList<TSQLEnv>();
112                                                for (int i = 0; i < servers.size(); i++) {
113                                                        Map server = (Map) servers.get(i);
114                                                        String dbVendor = (String) server.get("dbVendor");
115                                                        if (SQLUtil.isEmpty(dbVendor)) {
116                                                                sqlEnvs.add(new SqlflowShardedSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, server, baseDir));
117                                                        } else {
118                                                                sqlEnvs.add(new SqlflowShardedSQLEnv(defaultServer, defaultDatabase, defaultSchema, EDbVendor.valueOf(dbVendor), server, baseDir));
119                                                        }
120                                                }
121                                                return sqlEnvs.toArray(new TSQLEnv[0]);
122                                        }
123                                        else {
124                                                List servers = (List) json.get("servers");
125                                                if (servers == null)
126                                                        return null;
127                                                List<TSQLEnv> sqlEnvs = new ArrayList<TSQLEnv>();
128                                                for (int i = 0; i < servers.size(); i++) {
129                                                        Map server = (Map) servers.get(i);
130                                                        String dbVendor = (String) server.get("dbVendor");
131                                                        if (SQLUtil.isEmpty(dbVendor)) {
132                                                                sqlEnvs.add(new SqlflowSQLEnv(defaultServer, defaultDatabase, defaultSchema, vendor, server));
133                                                        } else {
134                                                                sqlEnvs.add(new SqlflowSQLEnv(defaultServer, defaultDatabase, defaultSchema, EDbVendor.valueOf(dbVendor), server));
135                                                        }
136                                                }
137                                                return sqlEnvs.toArray(new TSQLEnv[0]);
138                                        }
139                                }
140                        }
141                } catch (Exception e) {
142                        Logger.getLogger(TJSONSQLEnvParser.class.getName()).log(Level.WARNING, "Parse json failed.", e);
143                }
144                return null;
145        }
146}