001package gudusoft.gsqlparser.sqlenv.parser.sqlflow; 002 003import gudusoft.gsqlparser.EDbVendor; 004import gudusoft.gsqlparser.sqlenv.*; 005import gudusoft.gsqlparser.sqlenv.parser.sqldep.MultipleSQLDepSQLEnv; 006import gudusoft.gsqlparser.util.SQLUtil; 007 008import java.util.ArrayList; 009import java.util.List; 010import java.util.Map; 011import java.util.logging.Level; 012import java.util.logging.Logger; 013 014@SuppressWarnings("rawtypes") 015public class SqlflowSQLEnv extends TSQLEnv { 016 017 private Map server; 018 019 private Boolean init = false; 020 021 public SqlflowSQLEnv(String defaultServer, String defaultDatabase, String defaultSchema, EDbVendor dbVendor, Map server) { 022 super(dbVendor); 023 if(!SQLUtil.isEmpty(defaultServer) && !defaultServer.equals(TSQLEnv.DEFAULT_SERVER_NAME)) { 024 setDefaultServerName(defaultServer); 025 } 026 if(!SQLUtil.isEmpty(defaultDatabase) && !defaultDatabase.equals(TSQLEnv.DEFAULT_DB_NAME)) { 027 setDefaultCatalogName(defaultDatabase); 028 } 029 if(!SQLUtil.isEmpty(defaultSchema) && !defaultSchema.equals(TSQLEnv.DEFAULT_SCHEMA_NAME)) { 030 setDefaultSchemaName(defaultSchema); 031 } 032 this.server = server; 033 initSQLEnv(); 034 } 035 036 @Override 037 public void initSQLEnv() { 038 synchronized (init) { 039 if (init) 040 return; 041 String dbVendor = (String) server.get("dbVendor"); 042 if (!SQLUtil.isEmpty((String) server.get("name"))) { 043 this.setDefaultServerName((String) server.get("name")); 044 } 045 EDbVendor vendor = getDBVendor(); 046 if (dbVendor != null) { 047 vendor = EDbVendor.valueOf(dbVendor); 048 } 049 050 boolean supportsCatalogs = TSQLEnv.supportCatalog(vendor); 051 boolean supportsSchemas = TSQLEnv.supportSchema(vendor); 052 053 // Synonyms are resolved in a final pass so that their source tables, 054 // which may live in another schema/catalog, are already loaded. 055 List<Object[]> pendingSynonyms = new ArrayList<Object[]>(); 056 057 try { 058 if (supportsCatalogs && supportsSchemas) { 059 List databases = (List) server.get("databases"); 060 if (databases != null) { 061 for (int i = 0; i < databases.size(); i++) { 062 Map jsonDatabase = (Map) databases.get(i); 063 String databaseName = (String) jsonDatabase.get("name"); 064 List schemas = (List) jsonDatabase.get("schemas"); 065 if (schemas == null) { 066 continue; 067 } 068 TSQLCatalog sqlCatalog = getSQLCatalog(databaseName, true); 069 for (int j = 0; j < schemas.size(); j++) { 070 Map jsonSchema = (Map) schemas.get(j); 071 String schemaName = (String) jsonSchema.get("name"); 072 TSQLSchema sqlSchema = sqlCatalog.getSchema(schemaName, true); 073 appendTables(jsonSchema, sqlSchema); 074 appendPackages(jsonSchema, sqlSchema); 075 appendProcedures(jsonSchema, sqlSchema, null); 076 collectSynonyms(jsonSchema, sqlSchema, pendingSynonyms); 077 } 078 } 079 } 080 } else if (supportsCatalogs) { 081 List databases = (List) server.get("databases"); 082 if (databases != null) { 083 for (int i = 0; i < databases.size(); i++) { 084 Map jsonDatabase = (Map) databases.get(i); 085 String databaseName = (String) jsonDatabase.get("name"); 086 TSQLCatalog sqlCatalog = getSQLCatalog(databaseName, true); 087 TSQLSchema sqlSchema = sqlCatalog.getSchema(TSQLEnv.DEFAULT_SCHEMA_NAME, true); 088 appendTables(jsonDatabase, sqlSchema); 089 appendPackages(jsonDatabase, sqlSchema); 090 appendProcedures(jsonDatabase, sqlSchema, null); 091 collectSynonyms(jsonDatabase, sqlSchema, pendingSynonyms); 092 } 093 } 094 } else if (supportsSchemas) { 095 List schemas = (List) server.get("schemas"); 096 if (schemas != null) { 097 for (int i = 0; i < schemas.size(); i++) { 098 Map jsonSchema = (Map) schemas.get(i); 099 String schemaName = (String) jsonSchema.get("name"); 100 TSQLCatalog sqlCatalog = getSQLCatalog(TSQLEnv.DEFAULT_DB_NAME, true); 101 TSQLSchema sqlSchema = sqlCatalog.getSchema(schemaName, true); 102 appendTables(jsonSchema, sqlSchema); 103 appendPackages(jsonSchema, sqlSchema); 104 appendProcedures(jsonSchema, sqlSchema, null); 105 collectSynonyms(jsonSchema, sqlSchema, pendingSynonyms); 106 } 107 } 108 } 109 for (int i = 0; i < pendingSynonyms.size(); i++) { 110 Object[] pending = pendingSynonyms.get(i); 111 appendSynonym((TSQLSchema) pending[0], (Map) pending[1]); 112 } 113 } catch (Exception e) { 114 Logger.getLogger(MultipleSQLDepSQLEnv.class.getName()).log(Level.WARNING, "Parse json failed.", e); 115 } 116 init = true; 117 } 118 } 119 120 private void appendTables(Map jsonSchema, TSQLSchema sqlSchema) { 121 List tables = (List) jsonSchema.get("tables"); 122 List views = (List) jsonSchema.get("views"); 123 List dbObjs = new ArrayList(); 124 if (tables != null) { 125 dbObjs.addAll(tables); 126 } 127 if (views != null) { 128 dbObjs.addAll(views); 129 } 130 for (int k = 0; k < dbObjs.size(); k++) { 131 Map jsonTable = (Map) dbObjs.get(k); 132 String tableName = (String) jsonTable.get("name"); 133 TSQLTable sqlTable = sqlSchema.createTable(tableName, 3); 134 String type = (String) jsonTable.get("type"); 135 if (type != null && type.toLowerCase().indexOf("view") != -1) { 136 sqlTable.setView(true); 137 } 138 List columns = (List) jsonTable.get("columns"); 139 if(columns!=null) { 140 for (int l = 0; l < columns.size(); l++) { 141 Map jsonColumn = (Map) columns.get(l); 142 sqlTable.addColumn((String) jsonColumn.get("name")); 143 } 144 } 145 } 146 } 147 148 private void collectSynonyms(Map jsonSchema, TSQLSchema sqlSchema, List<Object[]> pendingSynonyms) { 149 List synonyms = (List) jsonSchema.get("synonyms"); 150 if (synonyms == null) { 151 return; 152 } 153 for (int k = 0; k < synonyms.size(); k++) { 154 Map jsonSynonym = (Map) synonyms.get(k); 155 if (jsonSynonym == null) { 156 continue; 157 } 158 pendingSynonyms.add(new Object[] { sqlSchema, jsonSynonym }); 159 } 160 } 161 162 private void appendSynonym(TSQLSchema sqlSchema, Map jsonSynonym) { 163 String synonymName = (String) jsonSynonym.get("name"); 164 if (SQLUtil.isEmpty(synonymName)) { 165 return; 166 } 167 // Register the synonym as a table alias inside its own schema. 168 TSQLTable synonymTable = sqlSchema.createTable(synonymName, 3); 169 if (synonymTable == null) { 170 return; 171 } 172 String sourceName = (String) jsonSynonym.get("sourceName"); 173 if (SQLUtil.isEmpty(sourceName)) { 174 return; 175 } 176 String sourceSchema = (String) jsonSynonym.get("sourceSchema"); 177 // Inherit the source object's columns so the synonym resolves like the target. 178 TSQLTable sourceTable = findSourceTable(sourceSchema, sourceName); 179 if (sourceTable != null) { 180 if (sourceTable.isView()) { 181 synonymTable.setView(true); 182 } 183 List<String> columns = sourceTable.getColumns(true); 184 if (columns != null) { 185 for (int i = 0; i < columns.size(); i++) { 186 String column = columns.get(i); 187 if (!SQLUtil.isEmpty(column)) { 188 synonymTable.addColumn(column); 189 } 190 } 191 } 192 } 193 } 194 195 private TSQLTable findSourceTable(String sourceSchema, String sourceName) { 196 if (!SQLUtil.isEmpty(sourceSchema)) { 197 for (TSQLCatalog catalog : getCatalogList()) { 198 TSQLSchema schema = catalog.getSchema(sourceSchema, false); 199 if (schema != null) { 200 TSQLTable table = schema.findTable(sourceName); 201 if (table != null) { 202 return table; 203 } 204 } 205 } 206 } 207 // Fallback: search across all schemas by the simple source name. 208 for (TSQLCatalog catalog : getCatalogList()) { 209 for (TSQLSchema schema : catalog.getSchemaList()) { 210 TSQLTable table = schema.findTable(sourceName); 211 if (table != null) { 212 return table; 213 } 214 } 215 } 216 return null; 217 } 218 219 private void appendPackages(Map jsonSchema, TSQLSchema sqlSchema) { 220 List packages = (List) jsonSchema.get("packages"); 221 List dbObjs = new ArrayList(); 222 if (packages != null) { 223 dbObjs.addAll(packages); 224 } 225 for (int k = 0; k < dbObjs.size(); k++) { 226 Map jsonOraclePackage = (Map) dbObjs.get(k); 227 String packageName = (String) jsonOraclePackage.get("name"); 228 TSQLOraclePackage sqlPackage = sqlSchema.createOraclePackage(packageName); 229 appendProcedures(jsonOraclePackage, sqlSchema, sqlPackage); 230 } 231 } 232 233 private void appendProcedures(Map jsonProcedureParent, TSQLSchema sqlSchema, TSQLOraclePackage sqlPackage) { 234 if (jsonProcedureParent.containsKey("procedures")) { 235 List<Map> procedures = (List<Map>) jsonProcedureParent.get("procedures"); 236 if(procedures!=null) { 237 for (Map procedure : procedures) { 238 String procedureName = (String) procedure.get("name"); 239 if (sqlPackage != null) { 240 sqlPackage.createProcedure(procedureName); 241 } else { 242 sqlSchema.createProcedure(procedureName); 243 } 244 } 245 } 246 } 247 if (jsonProcedureParent.containsKey("functions")) { 248 List<Map> functions = (List<Map>) jsonProcedureParent.get("functions"); 249 if (functions != null) { 250 for (Map function : functions) { 251 String functionName = (String) function.get("name"); 252 if (sqlPackage != null) { 253 sqlPackage.createFunction(functionName); 254 } else { 255 sqlSchema.createFunction(functionName); 256 } 257 } 258 } 259 } 260 if (jsonProcedureParent.containsKey("triggers")) { 261 List<Map> triggers = (List<Map>) jsonProcedureParent.get("triggers"); 262 if (triggers != null) { 263 for (Map trigger : triggers) { 264 String triggerName = (String) trigger.get("name"); 265 if (sqlPackage != null) { 266 sqlPackage.createTrigger(triggerName); 267 } else { 268 sqlSchema.createTrigger(triggerName); 269 } 270 } 271 } 272 } 273 } 274}