diff --git a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/app/RunBB.java b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/app/RunBB.java index 63dd524d..47e5b043 100644 --- a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/app/RunBB.java +++ b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/app/RunBB.java @@ -3,67 +3,64 @@ import java.util.logging.Logger; import ca.sfu.cs.common.Configuration.Config; +import ca.sfu.cs.factorbase.database.FactorBaseDataBase; +import ca.sfu.cs.factorbase.database.MySQLFactorBaseDataBase; import ca.sfu.cs.factorbase.exporter.csvexporter.CSVPrecomputor; import ca.sfu.cs.factorbase.tables.BayesBaseCT_SortMerge; import ca.sfu.cs.factorbase.tables.BayesBaseH; import ca.sfu.cs.factorbase.tables.KeepTablesOnly; -import ca.sfu.cs.factorbase.tables.MakeSetup; import ca.sfu.cs.factorbase.util.LoggerConfig; -/* July 3rd, 2014, zqian - * input: +/** + * July 3rd, 2014, zqian + * input: * @database@ (original data based on ER diagram) - * output: + * output: * @database@_BN (e.g. _CP, Path_BayesNets, Score) - * @database@_CT (e.g. BiggestRchain_CT) - * @database@_setup (preconditions for learning) - * - * */ + * @database@_CT (e.g. BiggestRchain_CT) + * @database@_setup (preconditions for learning) + */ public class RunBB { - static String isAutomaticSetup; - private static Logger logger = Logger.getLogger(RunBB.class.getName()); - - public static void main(String[] args) throws Exception { - LoggerConfig.setGlobalLevel(); - long t1 = System.currentTimeMillis(); - logger.info("Start Program..."); - setVarsFromConfig(); - if (isAutomaticSetup.equals("1")) { - MakeSetup.runMS(); - logger.info("Setup database is ready."); - } else { - logger.info("Setup database exists."); - } - runBBLearner(); - - long t2 = System.currentTimeMillis(); - logger.info("Total Running time is " + (t2-t1) + "ms."); - } - - - public static void setVarsFromConfig(){ - Config conf = new Config(); - //1: run Setup; 0: not run - isAutomaticSetup = conf.getProperty("AutomaticSetup"); - } - - public static void runBBLearner() throws Exception { - - //assumes that dbname is in config file and that dbname_setup exists. + private static Logger logger = Logger.getLogger(RunBB.class.getName()); - BayesBaseCT_SortMerge.buildCT(); - logger.info("The CT database is ready for use."); - logger.info("*********************************************************"); - CSVPrecomputor.runCSV(); - logger.info("CSV files are generated."); - logger.info("*********************************************************"); - BayesBaseH.runBBH(); - logger.info("\nFinish running BayesBaseH."); - logger.info("*********************************************************"); - logger.info("Cleaning CT database"); - //Now eliminate temporary tables. Keep only the tables for the longest Rchain. Turn this off for debugging.// - KeepTablesOnly.Drop_tmpTables(); - } + public static void main(String[] args) throws Exception { + long t1 = System.currentTimeMillis(); + LoggerConfig.setGlobalLevel(); + Config config = new Config(); + logger.info("Start Program..."); -} + FactorBaseDataBase factorBaseDatabase = new MySQLFactorBaseDataBase( + config.getProperty("dbaddress"), + config.getProperty("dbname"), + config.getProperty("dbusername"), + config.getProperty("dbpassword") + ); + + // Generate the setup database if specified to. + if (config.getProperty("AutomaticSetup").equals("1")) { + factorBaseDatabase.setupDatabase(); + logger.info("Setup database is ready."); + } else { + logger.info("Setup database exists."); + } + + // Learn a Bayesian Network. + BayesBaseCT_SortMerge.buildCT(); + logger.info("The CT database is ready for use."); + logger.info("*********************************************************"); + CSVPrecomputor.runCSV(); + logger.info("CSV files are generated."); + logger.info("*********************************************************"); + BayesBaseH.runBBH(); + logger.info("\nFinish running BayesBaseH."); + logger.info("*********************************************************"); + + // Now eliminate temporary tables. Keep only the tables for the longest Rchain. Turn this off for debugging. + logger.info("Cleaning CT database"); + KeepTablesOnly.Drop_tmpTables(); + + long t2 = System.currentTimeMillis(); + logger.info("Total Running time is " + (t2 - t1) + "ms."); + } +} \ No newline at end of file diff --git a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/FactorBaseDataBase.java b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/FactorBaseDataBase.java new file mode 100644 index 00000000..b2808ca1 --- /dev/null +++ b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/FactorBaseDataBase.java @@ -0,0 +1,16 @@ +package ca.sfu.cs.factorbase.database; + +import ca.sfu.cs.factorbase.exception.DataBaseException; + +/** + * Methods expected to be implemented to enable the extraction of data from a database for FactorBase. + */ +public interface FactorBaseDataBase { + /** + * This method should setup all the extra tables required for FactorBase to learn a Bayesian + * network for the provided database. + * + * @throws DataBaseException if an error occurs when attempting to access the database. + */ + void setupDatabase() throws DataBaseException; +} diff --git a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/MySQLFactorBaseDataBase.java b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/MySQLFactorBaseDataBase.java new file mode 100644 index 00000000..9cd3bf00 --- /dev/null +++ b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/database/MySQLFactorBaseDataBase.java @@ -0,0 +1,53 @@ +package ca.sfu.cs.factorbase.database; + +import java.io.IOException; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.text.MessageFormat; + +import ca.sfu.cs.common.Configuration.Config; +import ca.sfu.cs.factorbase.exception.DataBaseException; +import ca.sfu.cs.factorbase.util.BZScriptRunner; + +import com.mysql.jdbc.Connection; + +public class MySQLFactorBaseDataBase implements FactorBaseDataBase { + + private static final String CONNECTION_STRING = "jdbc:{0}/{1}"; + private String baseDatabaseName; + private Connection baseConnection; + + + /** + * Create connections to the databases required by FactorBase to learn a Bayesian Network. + * + * @param dbaddress - the address of the MySQL database to connect to. e.g. mysql://127.0.0.1 + * @param dbname - the name of the database with the original data. e.g. unielwin + * @param username - the username to use when accessing the database. + * @param password - the password to use when accessing the database. + * @throws SQLException if there is a problem connecting to the required databases. + */ + public MySQLFactorBaseDataBase(String dbaddress, String dbname, String username, String password) throws DataBaseException { + this.baseDatabaseName = dbname; + String baseConnectionString = MessageFormat.format(CONNECTION_STRING, dbaddress, dbname); + + try { + this.baseConnection = (Connection) DriverManager.getConnection(baseConnectionString, username, password); + } catch (SQLException e) { + throw new DataBaseException("Unable to connect to the provided database.", e); + } + } + + + @Override + public void setupDatabase() throws DataBaseException { + BZScriptRunner bzsr = new BZScriptRunner(this.baseDatabaseName, this.baseConnection); + try { + bzsr.runScript(Config.SCRIPTS_DIRECTORY + "setup.sql"); + bzsr.createSP(Config.SCRIPTS_DIRECTORY + "storedprocs.sql"); + bzsr.callSP("find_values"); + } catch (SQLException | IOException e) { + throw new DataBaseException("An error occurred when attempting to setup the database for FactorBase.", e); + } + } +} diff --git a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/exception/DataBaseException.java b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/exception/DataBaseException.java new file mode 100644 index 00000000..b49f7d99 --- /dev/null +++ b/code/factorbase/src/main/java/ca/sfu/cs/factorbase/exception/DataBaseException.java @@ -0,0 +1,26 @@ +package ca.sfu.cs.factorbase.exception; + + +/** + * Custom exception to wrap and throw the specific cause of an error. Should be thrown when an + * error occurs when attempting to access a database. + */ +public class DataBaseException extends Exception { + + + /** + * Serial version - auto-generated by Eclipse. + */ + private static final long serialVersionUID = -6623897407612813075L; + + + /** + * Used to wrap the root cause of an exception when attempting to access a database. + * + * @param message - useful message telling the user what has potentially gone wrong. + * @param cause - the exception that caused the error to occur when accessing a database. + */ + public DataBaseException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/code/factorbase/src/main/java/ca/sfu/cs/factorbase/tables/MakeSetup.java b/obsolete/refactored/MakeSetup.java similarity index 100% rename from code/factorbase/src/main/java/ca/sfu/cs/factorbase/tables/MakeSetup.java rename to obsolete/refactored/MakeSetup.java diff --git a/travis-resources/config.cfg b/travis-resources/config.cfg index d17380a1..61f3fe22 100644 --- a/travis-resources/config.cfg +++ b/travis-resources/config.cfg @@ -2,27 +2,15 @@ dbaddress = mysql://127.0.0.1 dbusername = root dbpassword = 123456 -dbBNschema = unielwin_BN -dbDataSchema = unielwin -dbOutputSchema = unielwin_db -pathBayesNet = Path_BayesNets - LinkAnalysis = 1 Continuous = 0 -Grounded = 0 dbname = unielwin AutomaticSetup = 1 LinkCorrelations = 1 ComputeKLD = 0 -dbschema = unielwin_BN -dbcounts = unielwin_db -dbcondprob = unielwin_db - UseLocal_CT = 0 -CrossValidation = 0 - LoggingLevel = info \ No newline at end of file