001 /* 002 * CRIMSON 003 * Copyright (c) 2006, Stephen Fisher, Susan Davidson, and Junhyong Kim, 004 * University of Pennsylvania. 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU General Public License as 008 * published by the Free Software Foundation; either version 2 of the 009 * License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, but 012 * WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 * 02110-1301 USA. 020 * 021 * @(#)SQL.java 022 */ 023 024 package edu.upenn.crimson.io; 025 026 import edu.upenn.crimson.*; 027 028 /** 029 * Most SQL commands are contained here, to facilitate portability to 030 * different databases. This object does not do anything other than 031 * return SQL code. The running of the code and processing of the 032 * output is done by the calling methods. 033 * 034 * @author Stephen Fisher 035 * @version $Id: SQL.java,v 1.20 2009/07/16 16:19:52 fisher Exp $ 036 */ 037 038 public class SQL { 039 040 /** This is the list of databases we can use. */ 041 private static final String[] dbTypes = { "Oracle", "MySQL" }; 042 043 /** 044 * This is a name of the database: -1 = none. By using an int to 045 * store the type we simplify tests for the type. 046 */ 047 private static int dbType = -1; 048 049 //-------------------------------------------------------------------------- 050 // Getters and Setters 051 052 public static String[] getDBTypes() { return dbTypes; } 053 054 /** Get the type of database (oracle or mysql). */ 055 public static String getDBType() { 056 if ((dbType > -1) && (dbType < dbTypes.length)) return dbTypes[dbType]; 057 else return ""; 058 } 059 060 /** 061 * Set the type of database (oracle or mysql). This will return 062 * false if "type" is not a valid database type or is empty. If 063 * successful, this will update the default dbType. 064 */ 065 public static boolean setDBType(String type) { 066 // make sure database is closed 067 if (Database.getConnection() != null) Database.close(); 068 if (Database.getConnection() != null) { 069 CrimsonUtils.printError("Can't close database connection, so the database type can be changed."); 070 return false; 071 } 072 073 if (CrimsonUtils.isEmpty(type)) { 074 dbType = -1; 075 return false; 076 } else { 077 for (int i = 0; i < dbTypes.length; i++) { 078 if (type.equalsIgnoreCase(dbTypes[i])) { 079 dbType = i; 080 081 // we found a match, so update the default 082 CrimsonUtils.setDBType(type); 083 084 // register the driver 085 try { 086 Class.forName(dbDriver()); 087 } catch (ClassNotFoundException e) { 088 e.printStackTrace(); 089 } 090 091 return true; 092 } 093 } 094 } 095 096 // if we get this far then the database type isn't valid. 097 String msg = "Unknown database type \'" + type + "\'. Valid types are : "; 098 for (int i = 0; i < dbTypes.length; i++) msg += dbTypes[i] + " "; 099 CrimsonUtils.printError(msg); 100 101 dbType = -1; 102 return false; 103 } 104 105 //-------------------------------------------------------------------------- 106 // Miscellaneous methods 107 108 /** 109 * Get the index value of the type of database. This value can be 110 * used to get the database type from dbTypes[]. 111 */ 112 public static int getDBTypeValue() { return dbType; } 113 114 public static boolean isOracle() { 115 if (dbType == 0) return true; 116 else return false; 117 } 118 119 public static boolean isMySQL() { 120 if (dbType == 1) return true; 121 else return false; 122 } 123 124 public static String dbDriver() { 125 // if (isOracle()) return "oracle.jdbc.driver.OracleDriver"; 126 if (isOracle()) return "oracle.jdbc.OracleDriver"; 127 if (isMySQL()) return "com.mysql.jdbc.Driver"; 128 return ""; 129 } 130 131 public static String dbURL() { 132 if (isOracle()) { 133 // alternate form for XE that includes login in url: 134 // jdbc:oracle:thin:<username>/<password>@<host>:<port>/XE 135 // for oracle (non-XE): 136 // jdbc:oracle:thin:<username>/<password>@<host>:<port>/ 137 // "jdbc:oracle:thin:@<host>:<port>/XE"; 138 return "jdbc:oracle:thin:@"; 139 } 140 if (isMySQL()) { 141 // "jdbc:mysql://<host>/<db>"; 142 return "jdbc:mysql://"; 143 } 144 return ""; 145 } 146 147 /** 148 * This will return the database date, as is used to test database 149 * connectivity. 150 */ 151 public static String getDate() { 152 if (isOracle()) return "select sysdate from dual"; 153 if (isMySQL()) return "select curdate()"; 154 return ""; 155 } 156 157 /** 158 * This code will return the table name, if the table exists in 159 * the database. 160 */ 161 public static String tableExists(String table) { 162 // if (isOracle()) return "select tname from tab where tname = '" + table + "'"; 163 if (isOracle()) return "select table_name from all_tables where table_name = '" + table + "'"; 164 if (isMySQL()) return "show tables like '" + table + "'"; 165 return ""; 166 } 167 168 /** This method will create all of the necessary tables. */ 169 public static String createTable(String table) { 170 String sql = "CREATE TABLE " + table; 171 172 if (table.equals("TREES")) { 173 if (isOracle()) { // ORACLE 174 sql += "( id VARCHAR2(100), "; 175 sql += "model_id VARCHAR2(100) CONSTRAINT tree2_fk REFERENCES MODELS (id), "; 176 sql += "notes VARCHAR2(4000), "; 177 sql += "num_species NUMBER(32,0) DEFAULT -1, "; 178 sql += "num_leaves NUMBER(32,0) DEFAULT -1, "; 179 sql += "is_binary NUMBER(1,0) DEFAULT 0 CONSTRAINT tree6_ck CHECK(is_binary >= 0 AND is_binary <= 1), "; 180 sql += "is_ultrametric NUMBER(1,0) DEFAULT 0 CONSTRAINT tree7_ck CHECK(is_ultrametric >= 0 AND is_ultrametric <= 1), "; 181 sql += "min_level NUMBER(32,0) DEFAULT -1, "; 182 sql += "max_level NUMBER(32,0) DEFAULT -1, "; 183 sql += "min_stem_length NUMBER DEFAULT -1.0, "; 184 sql += "max_stem_length NUMBER DEFAULT -1.0, "; 185 sql += "min_temp_depth NUMBER DEFAULT -1.0, "; 186 sql += "max_temp_depth NUMBER DEFAULT -1.0, "; 187 sql += "newick CLOB DEFAULT empty_clob(), "; 188 sql += "CONSTRAINT tree1_pk PRIMARY KEY (id) ) "; 189 } else if (isMySQL()) { // MySQL 190 sql += "( id VARCHAR(100), "; 191 sql += "model_id VARCHAR(100), "; 192 sql += "notes VARCHAR(4000), "; 193 sql += "num_species INT DEFAULT -1, "; 194 sql += "num_leaves INT DEFAULT -1, "; 195 sql += "is_binary TINYINT DEFAULT 0, "; 196 sql += "is_ultrametric TINYINT DEFAULT 0, "; 197 sql += "min_level INT DEFAULT -1, "; 198 sql += "max_level INT DEFAULT -1, "; 199 sql += "min_stem_length DOUBLE DEFAULT -1.0, "; 200 sql += "max_stem_length DOUBLE DEFAULT -1.0, "; 201 sql += "min_temp_depth DOUBLE DEFAULT -1.0, "; 202 sql += "max_temp_depth DOUBLE DEFAULT -1.0, "; 203 sql += "newick LONGTEXT, "; 204 sql += "CONSTRAINT tree1_pk PRIMARY KEY (id), "; 205 sql += "CONSTRAINT tree2_fk FOREIGN KEY (model_id) REFERENCES MODELS (id) ON DELETE CASCADE, "; 206 sql += "CONSTRAINT tree6_ck CHECK (is_binary >= 0 AND is_binary <= 1), "; 207 sql += "CONSTRAINT tree7_ck CHECK (is_ultrametric >= 0 AND is_ultrametric <= 1) ) "; 208 } else { 209 return ""; 210 } 211 return sql; 212 213 /* 214 } else if (table.equals("SPECIES")) { 215 if (isOracle()) { // ORACLE 216 sql += "( id VARCHAR2(100), "; 217 sql += "notes VARCHAR2(4000), "; 218 sql += "trees VARCHAR2(4000), "; 219 sql += "is_leaf NUMBER(1,0) DEFAULT 0 CONSTRAINT species4_ck CHECK(is_leaf >= 0 AND is_leaf <= 1), "; 220 sql += "CONSTRAINT species1_pk PRIMARY KEY (id) ) "; 221 } else if (isMySQL()) { // MySQL 222 sql += "( id VARCHAR(100), "; 223 sql += "notes VARCHAR(4000), "; 224 sql += "trees VARCHAR(4000), "; 225 sql += "is_leaf TINYINT DEFAULT 0, "; 226 sql += "CONSTRAINT species1_pk PRIMARY KEY (id) ) "; 227 } else { 228 return ""; 229 } 230 return sql; 231 */ 232 233 } else if (table.equals("PARTITIONS")) { 234 if (isOracle()) { // ORACLE 235 sql += "( id VARCHAR2(100), "; 236 sql += "tree_id VARCHAR2(100) CONSTRAINT part2_fk REFERENCES TREES (id) ON DELETE CASCADE, "; 237 sql += "model_id VARCHAR2(100) CONSTRAINT part3_fk REFERENCES MODELS (id), "; 238 sql += "notes VARCHAR2(4000), "; 239 sql += "length NUMBER DEFAULT 0 CONSTRAINT part5_ck CHECK(length >= 0), "; 240 sql += "CONSTRAINT part1_pk PRIMARY KEY(id) ) "; 241 } else if (isMySQL()) { // MySQL 242 sql += "( id VARCHAR(100), "; 243 sql += "tree_id VARCHAR(100), "; 244 sql += "model_id VARCHAR(100), "; 245 sql += "notes VARCHAR(4000), "; 246 sql += "length INT DEFAULT 0, "; 247 sql += "CONSTRAINT part1_pk PRIMARY KEY(id), "; 248 sql += "CONSTRAINT part2_fk FOREIGN KEY (tree_id) REFERENCES TREES (id) ON DELETE CASCADE, "; 249 sql += "CONSTRAINT part3_fk FOREIGN KEY (model_id) REFERENCES MODELS (id), "; 250 sql += "CONSTRAINT part5_ck CHECK (length >= 0) ) "; 251 } else { 252 return ""; 253 } 254 return sql; 255 256 } else if (table.equals("PART_DATA")) { 257 if (isOracle()) { // ORACLE 258 sql += "( partition_id VARCHAR2(100) CONSTRAINT pd1_fk REFERENCES PARTITIONS (id) ON DELETE CASCADE, "; 259 sql += "species_id VARCHAR2(100), "; 260 sql += "model_id VARCHAR2(100) CONSTRAINT pd3_fk REFERENCES MODELS (id), "; 261 sql += "notes VARCHAR2(4000), "; 262 sql += "sequence CLOB DEFAULT empty_clob(), "; 263 sql += "structure CLOB DEFAULT empty_clob(), "; 264 sql += "CONSTRAINT pd1_pk PRIMARY KEY(partition_id, species_id) ) "; 265 } else if (isMySQL()) { // MySQL 266 sql += "( partition_id VARCHAR(100), "; 267 sql += "species_id VARCHAR(100), "; 268 sql += "model_id VARCHAR(100), "; 269 sql += "notes VARCHAR(4000), "; 270 sql += "sequence LONGTEXT, "; 271 sql += "structure LONGTEXT, "; 272 sql += "CONSTRAINT pd1_pk PRIMARY KEY (partition_id, species_id), "; 273 sql += "CONSTRAINT pd1_fk FOREIGN KEY (partition_id) REFERENCES PARTITIONS (id) ON DELETE CASCADE, "; 274 sql += "CONSTRAINT pd3_fk FOREIGN KEY (model_id) REFERENCES MODELS (id) ) "; 275 } else { 276 return ""; 277 } 278 return sql; 279 280 } else if (table.equals("MODELS")) { 281 if (isOracle()) { // ORACLE 282 sql += "( id VARCHAR2(100), "; 283 sql += "notes VARCHAR2(4000), "; 284 sql += "details CLOB DEFAULT empty_clob(), "; 285 sql += "CONSTRAINT model1_pk PRIMARY KEY (id) ) "; 286 } else if (isMySQL()) { // MySQL 287 sql += "( id VARCHAR(100), "; 288 sql += "notes VARCHAR(4000), "; 289 sql += "details LONGTEXT, "; 290 sql += "CONSTRAINT model1_pk PRIMARY KEY (id) ) "; 291 } else { 292 return ""; 293 } 294 return sql; 295 296 } else if (table.equals("QUERIES")) { 297 if (isOracle()) { // ORACLE 298 sql += "( id VARCHAR2(100), "; 299 sql += "tree_id VARCHAR2(100) CONSTRAINT query2_fk REFERENCES TREES (id), "; 300 sql += "notes VARCHAR2(4000), "; 301 sql += "leaf_select NUMBER(1,0) DEFAULT 0 CONSTRAINT query4_nn_ck NOT NULL "; 302 sql += " CHECK(leaf_select >= 0 AND leaf_select < 7), "; 303 sql += "num_leaves NUMBER(32,0) DEFAULT 0 CONSTRAINT query5_ck CHECK(num_leaves >= 0), "; 304 sql += "temp_depth_thresh NUMBER DEFAULT 0.0 CONSTRAINT query6_ck CHECK(temp_depth_thresh >= 0), "; 305 sql += "level_thresh NUMBER(32,0) DEFAULT 0 CONSTRAINT query7_ck CHECK(level_thresh >= 0), "; 306 sql += "leaves CLOB DEFAULT empty_clob(), "; 307 sql += "seq_select NUMBER(1,0) DEFAULT 0 CONSTRAINT query9_nn_ck NOT NULL "; 308 sql += " CHECK(seq_select >= 0 AND seq_select < 6), "; 309 sql += "num_pos NUMBER(32,0) DEFAULT 0 CONSTRAINT query10_ck CHECK(num_pos >= 0), "; 310 sql += "partitions CLOB DEFAULT empty_clob(), "; 311 sql += "positions CLOB DEFAULT empty_clob(), "; 312 sql += "seed NUMBER(32,0) DEFAULT -1 CONSTRAINT query13_ck CHECK(seed >= -1), "; 313 sql += "CONSTRAINT query1_pk PRIMARY KEY (id) ) "; 314 } else if (isMySQL()) { // MySQL 315 sql += "( id VARCHAR(100), "; 316 sql += "tree_id VARCHAR(100), "; 317 sql += "notes VARCHAR(4000), "; 318 sql += "leaf_select TINYINT NOT NULL DEFAULT 0, "; 319 sql += "num_leaves INT DEFAULT 0, "; 320 sql += "temp_depth_thresh DOUBLE DEFAULT 0.0, "; 321 sql += "level_thresh INT DEFAULT 0, "; 322 sql += "leaves LONGTEXT, "; 323 sql += "seq_select TINYINT NOT NULL DEFAULT 0, "; 324 sql += "num_pos INT DEFAULT 0, "; 325 sql += "partitions LONGTEXT, "; 326 sql += "positions LONGTEXT, "; 327 sql += "seed BIGINT DEFAULT -1, "; 328 sql += "CONSTRAINT query1_pk PRIMARY KEY (id), "; 329 sql += "CONSTRAINT query2_fk FOREIGN KEY (tree_id) REFERENCES TREES (id), "; 330 sql += "CONSTRAINT query4_nn_ck CHECK (leaf_select >= 0 AND leaf_select < 7), "; 331 sql += "CONSTRAINT query5_ck CHECK (num_leaves >= 0), "; 332 sql += "CONSTRAINT query6_ck CHECK (temp_depth_thresh >= 0), "; 333 sql += "CONSTRAINT query7_ck CHECK (level_thresh >= 0), "; 334 sql += "CONSTRAINT query9_nn_ck CHECK (seq_select >= 0 AND seq_select < 5), "; 335 sql += "CONSTRAINT query10_ck CHECK (num_pos >= 0), "; 336 sql += "CONSTRAINT query13_ck CHECK (seed >= -1) ) "; 337 } else { 338 return ""; 339 } 340 return sql; 341 } 342 return ""; 343 } 344 345 } // SQL.java