001package org.biojava.bio.program.unigene;
002
003import java.net.URL;
004import java.sql.SQLException;
005import java.sql.Statement;
006
007import org.biojava.bio.BioException;
008import org.biojava.utils.JDBCConnectionPool;
009
010/**
011 * <p>An implementatoin of UnigeneFactory that manages it's data in an SQL
012 * database.</p>
013 *
014 * <p><em>This class is for developers and power-users.</em> Usually you will
015 * not use this class directly, but rather use UnigeneTools.loadDatabase() with
016 * a jdbc URL.</p>
017 *
018 * <p>This class will store unigene data in a relational database with a schema
019 * defined by the resource src/org/biojava/bio/program/unigene/createUnigene.sql
020 * and currently only realy supports mysql. To import data to a newly created
021 * database, repeatedly call addCluster() on the UnigeneDB you get back.</p>
022 *
023 * @author Matthew Pocock
024 */
025public class SQLUnigeneFactory
026implements UnigeneFactory {
027  private static String CREATE_DB_STATEMENT;
028
029  private static String getCreateDBStatement() {
030    if(CREATE_DB_STATEMENT == null) {
031        /*
032      StringBuffer stmt = new StringBuffer();
033      BufferedReader stmtIn = new BufferedReader(
034        new InputStreamReader(
035          ClassTools.getClassLoader(SQLUnigeneFactory.class).getResourceAsStream(
036            "/org/biojava/bio/program/unigene/createUnigene.sql"
037          )
038        )
039      );
040      */
041        // commented as does not assign loaded class and is unclear what should do.
042    }
043    return CREATE_DB_STATEMENT;
044  }
045
046  /**
047   * Accepts all URLs that are of the jdbc protocol.
048   */
049  public boolean canAccept(URL dbURL) {
050    return dbURL.getProtocol().equals("jdbc");
051  }
052
053  public UnigeneDB loadUnigene(URL dbURL)
054  throws BioException {
055    if(!canAccept(dbURL)) {
056      throw new BioException("Can't resolve url to an sql unigene db: " + dbURL);
057    }
058
059    JDBCConnectionPool conPool = new JDBCConnectionPool(dbURL.toString());
060
061    return new SQLUnigeneDB(conPool);
062  }
063
064  public UnigeneDB createUnigene(URL dbURL)
065  throws BioException {
066    String dbString = dbURL.toString();
067    int lastSlash = dbString.lastIndexOf("/");
068    String rootURL = dbString.substring(0, lastSlash);
069    String dbName = dbString.substring(lastSlash + 1);
070
071    JDBCConnectionPool connPool = new JDBCConnectionPool(rootURL);
072
073    Statement stmt = null;
074    try {
075      stmt = connPool.takeStatement();
076      stmt.execute("create database " + dbName);
077      stmt.execute("use " + dbName);
078      stmt.execute(getCreateDBStatement());
079    } catch (SQLException se) {
080      throw new BioException("Could not create database", se);
081    } finally {
082      try {
083        connPool.putStatement(stmt);
084      } catch (SQLException se) {
085        // not much we can do about this
086      }
087    }
088
089    return new SQLUnigeneDB(connPool);
090  }
091}