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 String sourceName = (String) jsonSynonym.get("sourceName"); 168 if (SQLUtil.isEmpty(sourceName)) { 169 return; 170 } 171 String sourceDatabase = (String) jsonSynonym.get("sourceDatabase"); 172 String sourceSchema = (String) jsonSynonym.get("sourceSchema"); 173 // Register the synonym as a TSQLSynonyms carrying its base target. The 174 // owning TSQLEnv dereferences the synonym to its base table/view at 175 // lookup time via TSQLSynonyms.resolveBaseTable(), so the synonym 176 // transparently exposes the base object's columns without us copying 177 // them up-front (which previously also broke cross-database / forward 178 // references). 179 sqlSchema.createSynonyms(synonymName, sourceDatabase, sourceSchema, sourceName); 180 } 181 182 private void appendPackages(Map jsonSchema, TSQLSchema sqlSchema) { 183 List packages = (List) jsonSchema.get("packages"); 184 List dbObjs = new ArrayList(); 185 if (packages != null) { 186 dbObjs.addAll(packages); 187 } 188 for (int k = 0; k < dbObjs.size(); k++) { 189 Map jsonOraclePackage = (Map) dbObjs.get(k); 190 String packageName = (String) jsonOraclePackage.get("name"); 191 TSQLOraclePackage sqlPackage = sqlSchema.createOraclePackage(packageName); 192 appendProcedures(jsonOraclePackage, sqlSchema, sqlPackage); 193 } 194 } 195 196 private void appendProcedures(Map jsonProcedureParent, TSQLSchema sqlSchema, TSQLOraclePackage sqlPackage) { 197 if (jsonProcedureParent.containsKey("procedures")) { 198 List<Map> procedures = (List<Map>) jsonProcedureParent.get("procedures"); 199 if(procedures!=null) { 200 for (Map procedure : procedures) { 201 String procedureName = (String) procedure.get("name"); 202 if (sqlPackage != null) { 203 sqlPackage.createProcedure(procedureName); 204 } else { 205 sqlSchema.createProcedure(procedureName); 206 } 207 } 208 } 209 } 210 if (jsonProcedureParent.containsKey("functions")) { 211 List<Map> functions = (List<Map>) jsonProcedureParent.get("functions"); 212 if (functions != null) { 213 for (Map function : functions) { 214 String functionName = (String) function.get("name"); 215 if (sqlPackage != null) { 216 sqlPackage.createFunction(functionName); 217 } else { 218 sqlSchema.createFunction(functionName); 219 } 220 } 221 } 222 } 223 if (jsonProcedureParent.containsKey("triggers")) { 224 List<Map> triggers = (List<Map>) jsonProcedureParent.get("triggers"); 225 if (triggers != null) { 226 for (Map trigger : triggers) { 227 String triggerName = (String) trigger.get("name"); 228 if (sqlPackage != null) { 229 sqlPackage.createTrigger(triggerName); 230 } else { 231 sqlSchema.createTrigger(triggerName); 232 } 233 } 234 } 235 } 236 } 237}