Package net.sourceforge.javautil.database.mysql

Source Code of net.sourceforge.javautil.database.mysql.MysqlEmbeddedDatabaseServer

package net.sourceforge.javautil.database.mysql;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;

import net.sourceforge.javautil.classloader.impl.ClassContext;
import net.sourceforge.javautil.classloader.impl.StandardClassLoaderHeiarchy;
import net.sourceforge.javautil.classloader.source.InternalZipClassSource;
import net.sourceforge.javautil.classloader.source.ZipClassSource;
import net.sourceforge.javautil.common.ThreadUtil;
import net.sourceforge.javautil.common.VirtualArtifactUtil;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.IModifiableInputSource.MemoryInputSource;
import net.sourceforge.javautil.common.io.impl.SystemDirectory;
import net.sourceforge.javautil.common.io.impl.SystemFile;
import net.sourceforge.javautil.common.password.IPassword;
import net.sourceforge.javautil.common.reflection.proxy.ReflectiveObjectProxy;
import net.sourceforge.javautil.database.DatabaseServerAbstract;
import net.sourceforge.javautil.datasource.IDataSourceDescriptor;
import net.sourceforge.javautil.datasource.DataSourceDescriptorStandard;
import net.sourceforge.javautil.lifecycle.ILifecycle.PhaseType;
import net.sourceforge.javautil.lifecycle.annotation.Phase;

/**
* The standard implementation for using MXJ for emebedded mysql.<br/><br/>
*
* The actual MXJ jar and packaged mysqld binary and initialization folders are not
* distributed with this library and were not currently available
* via maven when this was last updated.<br/><br/>
*
* You must provide in the class path the  packaged jar with the binary
* and other resources as distributed by MySQL
* <a href="http://dev.mysql.com/downloads/connector/mxj/5.0.html">here</a>.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: MysqlEmbeddedDatabaseServer.java 2477 2010-10-25 03:42:34Z ponderator $
*/
public class MysqlEmbeddedDatabaseServer extends DatabaseServerAbstract {
 
  /**
   * @return A special internal classloader for loading the MXJ classes
   */
  protected static ClassLoader createMysqlMXJClassLoader (IVirtualFile mxjJar, IVirtualFile mxjDbFileJar) {
    return new ClassContext(new StandardClassLoaderHeiarchy(),
      new ZipClassSource(mxjJar.getURL()),
      new ZipClassSource(mxjDbFileJar.getURL())
    );
  }
 
  protected final PrintStream outputStream;
  protected final PrintStream errorStream;
 
  protected final String username;
  protected final IPassword password;
  protected final int port;
  protected final boolean skipInnoDb;
 
  protected final File processIdFile;
  protected final File portFile;
 
  protected final File dataDirectory;
  protected final File baseDirectory;
 
  protected final ClassLoader mxjLoader;
  protected final String mxjVersion;
 
  protected MysqldResource resource;
  protected boolean running = false;
 
  protected String maxAllowedPacket = "256M";

  /**
   * This assumes the use of the current thread level context class loader.
   *
   * @see MysqlEmbeddedDatabaseServer#MysqlEmbeddedDatabaseServer(ClassLoader, SystemDirectory, PrintStream, PrintStream, String, IPassword, int, boolean)M
   */
  public MysqlEmbeddedDatabaseServer(String mxjVersion, SystemDirectory root, PrintStream outputStream, PrintStream errorStream,
      String username, IPassword password, int port, boolean skipInnoDb) {
    this(Thread.currentThread().getContextClassLoader(), mxjVersion, root, outputStream, errorStream, username, password, port, skipInnoDb);
  }

  public MysqlEmbeddedDatabaseServer(
      IVirtualFile mxjJar,
      IVirtualFile mxjDbFilesJar,
      String mxjVersion,
      SystemDirectory root, PrintStream outputStream,
      PrintStream errorStream, String username, IPassword password,
      int port, boolean skipInnoDb
  ) {
    this(createMysqlMXJClassLoader(mxjJar, mxjDbFilesJar), mxjVersion, root, outputStream, errorStream, username, password, port, skipInnoDb);
  }
 
  /**
   * @param mxjLoader The class loader for accessing the MXJ connector and db files
   * @param root The root directory of the server
   * @param outputStream The output stream for server output
   * @param errorStream The error stream for server errors
   * @param username The username, or null if no authentication should be used
   * @param password The password
   * @param port The port
   * @param skipInnoDb True if innodb should be skipped, otherwise false
   */
  public MysqlEmbeddedDatabaseServer(ClassLoader mxjLoader, String mxjVersion, SystemDirectory root, PrintStream outputStream, PrintStream errorStream,
      String username, IPassword password, int port, boolean skipInnoDb) {
   
    super("Mysql Embedded Server", root);
    this.mxjLoader = mxjLoader;
    this.mxjVersion = mxjVersion;
    this.outputStream = outputStream == null ? System.out : outputStream;
    this.errorStream = errorStream == null ? System.err : errorStream;
    this.username = username;
    this.password = password;
    this.port = port;
    this.skipInnoDb = skipInnoDb;
   
    File rootDirectory = this.root.getRealArtifact();
    this.baseDirectory = new File(rootDirectory, "base");
    this.dataDirectory = new File(rootDirectory, "data");
   
    this.processIdFile = new File(dataDirectory, "MysqldResource.pid");
    this.portFile = new File(dataDirectory, "MysqldResource.port");
  }

  /**
   * @return The setting passed to the --max_allowed_packet parameter passed to the server.
   */
  public String getMaxAllowedPacket() { return maxAllowedPacket; }
 
  /**
   * If this is set after the server is started, the server will need to be restarted in order for the
   * new setting to be put into effect.
   *
   * @see #getMaxAllowedPacket()
   */
  public void setMaxAllowedPacket(String maxAllowedPacket) { this.maxAllowedPacket = maxAllowedPacket; }

  /**
   * @return The output stream being used for the server
   */
  public PrintStream getOutputStream() { return outputStream; }

  /**
   * @return The error stream being used for the server
   */
  public PrintStream getErrorStream() { return errorStream; }

  /**
   * @return The username the server was setup with, or null if no authentication is being used
   */
  public String getUsername() { return username; }

  /**
   * @return The password the server was setup with, or null if no authentication is being used
   */
  public IPassword getPassword() { return password; }

  /**
   * @return The port the server was setup with
   */
  public int getPort() { return port; }

  /**
   * @return True if this server will skip innodb initialization, otherwise false
   */
  public boolean isSkipInnoDb() { return skipInnoDb; }

  /**
   * @return The proccess id file used by the server
   */
  public File getProcessIdFile() { return processIdFile; }

  /**
   * @return The port file used by the server
   */
  public File getPortFile() { return portFile; }

  /**
   * @return The data directory for this server
   */
  public File getDataDirectory() { return dataDirectory; }

  /**
   * @return The base server directory
   */
  public File getBaseDirectory() { return baseDirectory; }

  public boolean isDatabaseExists(String name) { return new File(this.dataDirectory, name).exists(); }

  public Connection createConnection(String databaseName, String username, IPassword password) throws SQLException {
    String url = this.createConnectionURL(databaseName);
    return username == null ? DriverManager.getConnection(url) : DriverManager.getConnection(url, username, new String(password.getPassword()));
  }

  public boolean createDatabase(String name, String username, IPassword password) {
    File databaseDir = new File(this.dataDirectory, name);
    if (databaseDir.exists()) return false;
    return databaseDir.mkdir();
  }

  public IDataSourceDescriptor createDescriptor(String name, String databaseName, String username) {
    return new DataSourceDescriptorStandard(name, "com.mysql.jdbc.Driver", this.createConnectionURL(databaseName), username);
  }

  public MysqlConnectionPoolDataSource createDataSource(String databaseName, String username, IPassword password) throws SQLException {
    MysqlConnectionPoolDataSource pooled = new MysqlConnectionPoolDataSource();
    pooled.setUser(username);
    pooled.setPassword(new String(password.getPassword()));
    pooled.setDatabaseName(databaseName);
    pooled.setPort(this.port);
    pooled.setLocalSocketAddress("localhost");
    return pooled;
  }

  @Phase(value=PhaseType.START) private void startMysql() {
    this.resource = ReflectiveObjectProxy.newInstance(
      Thread.currentThread().getContextClassLoader(),
      mxjLoader, MysqldResource.class,
     
      baseDirectory, dataDirectory, mxjVersion, this.outputStream, this.errorStream
    );
    this.resource.setKillDelay(5);
   
    if (this.resource.isRunning()) { this.resource.shutdown(); }
   
    if (this.processIdFile.exists()) this.processIdFile.delete();
    if (this.portFile.exists()) this.portFile.delete();
   
    Map<String, String> options = new HashMap<String, String>();
    options.put("port", String.valueOf( port ));
    options.put("initialize-user", username == null ? "false" : "true");
   
    if (this.username != null) {
      options.put("initialize-user.user", username);
      options.put("initialize-user.password", new String(password.getPassword()));
    }
   
    if (this.maxAllowedPacket != null) {
      options.put("max_allowed_packet", this.maxAllowedPacket);
    }
   
    options.put("skip-innodb", String.valueOf( this.skipInnoDb ));
   
    this.resource.start("Mysql Embedded Thread", options, true);
   
    ThreadUtil.sleep(500);
    if (!this.resource.isRunning())
      throw new IllegalStateException("Mysql Instance not running after start()");
  }

  @Phase(value=PhaseType.STOP) private void stopMysql() {
    try {
      if (this.resource.isRunning()) {
        this.resource.shutdown();
      }
      this.running = false;
    } catch (Throwable t) {
      ThrowableManagerRegistry.caught(t);
    }
  }
 
  /**
   * Create a connection URL for the database
   */
  protected String createConnectionURL (String databaseName) {
    return "jdbc:mysql://localhost:" + port + "/" + databaseName + (this.maxAllowedPacket != null ? "?maxAllowedPacket=" + this.maxAllowedPacket : "");
  }
 
}
TOP

Related Classes of net.sourceforge.javautil.database.mysql.MysqlEmbeddedDatabaseServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.