Archive for March, 2008

Dumping a MySQL database from Java

Saturday, March 29th, 2008

Either you call the mysqldump binary from java :

import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;

public class MySQLDumper {

private static String ip="localhost";
private static String port="3306";
private static String database="dbname";
private static String user="root";
private static String pass="a";
private static String path="E:\\Users
dbname.sql";

public static void export(){
String dumpCommand = "mysqldump " + database + " -h " + ip + " -u " + user +" -p" + pass;
Runtime rt = Runtime.getRuntime();
File test=new File(path);
PrintStream ps;

try{
Process child = rt.exec(dumpCommand);
ps=new PrintStream(test);
InputStream in = child.getInputStream();
int ch;
while ((ch = in.read()) != -1) {
ps.write(ch);
System.out.write(ch); //to view it by console
}

InputStream err = child.getErrorStream();
while ((ch = err.read()) != -1) {
System.out.write(ch);
}
}catch(Exception exc) {
exc.printStackTrace();
}
}

public static void main(String args[]){
export();
}
}

or you use a java implementation of the tool itself:
MySQL Dump in Java

Which actually leads to the following code :

/**
* Copyright (c) 2007, Wave2 Limited
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of Wave2 Limited nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.binarystor.mysql;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import org.kohsuke.args4j.*;
import static org.kohsuke.args4j.ExampleMode.ALL;

/**
 *
 * @author Alan Snelson
 */
public class MySQLDump {

    //Command Line Arguments
    @Option(name="--help")
    private boolean help;
    @Option(name="-h",usage="MySQL Server Hostname")
    private String hostname;
    @Option(name="-u",usage="MySQL Username")
    private String username;
    @Option(name="-p",usage="MySQL Password")
    private String password;
    // receives other command line parameters than options
    @Argument
    private List arguments = new ArrayList();

    private static String version = "0.1";
    private String database = null;
    private Connection conn = null;
    private DatabaseMetaData databaseMetaData;
    private String databaseProductVersion = null;
    private String mysqlVersion = null;

    /**
    * Default contructor for MySQLDump.
    */
    public MySQLDump() {

    }

    /**
    * Create a new instance of MySQLDump using default database.
    *
    * @param  host      MySQL Server Hostname
    * @param  username  MySQL Username
    * @param  password  MySQL Password
    */
    public MySQLDump(String host, String username, String password) throws SQLException {
        try{
            connect(host, username, password, "mysql");
        }
        catch (SQLException se){
            throw se;
        }

    }

    /**
    * Create a new instance of MySQLDump using supplied database.
    *
    * @param  host      MySQL Server Hostname
    * @param  username  MySQL Username
    * @param  password  MySQL Password
    * @param  db        Default database
    */
    public MySQLDump(String host, String username, String password, String db) throws SQLException{
        try{
            connect(host, username, password, db);
        }
        catch (SQLException se){
            throw se;
        }
    }

    /**
    * Connect to MySQL server
    *
    * @param  host      MySQL Server Hostname
    * @param  username  MySQL Username
    * @param  password  MySQL Password
    * @param  db        Default database
    */
    public void connect(String host, String username, String password, String db) throws SQLException{
        try
        {
            Class.forName ("com.mysql.jdbc.Driver").newInstance ();
            conn = DriverManager.getConnection ("jdbc:mysql://" + host + "/" + db, username, password);
            databaseMetaData = conn.getMetaData();
            databaseProductVersion = databaseMetaData.getDatabaseProductVersion();
            hostname = host;
            database = db;
            System.out.println ("Database connection established");
        }
        catch (SQLException se){
            throw se;
        }
        catch (Exception e)
        {
            System.err.println ("Cannot connect to database server");
        }
    }

    public File dumpAllDatabases(){
        return null;
    }

    public String dumpCreateDatabase(String database) {
        String createDatabase = null;
        try{
            Statement s = conn.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            s.executeQuery ("SHOW CREATE DATABASE " + database);
            ResultSet rs = s.getResultSet ();
            while (rs.next ())
            {
                createDatabase = rs.getString("Create Database") + ";";
            }
        } catch (SQLException e) {

        }
        return createDatabase;
    } 

    public File dumpDatabase(String database){
        return null;
    }

    public File dumpAllTables(String database){
        return null;
    }

    public String dumpCreateTable(BufferedWriter out, String table) {
        String createTable = null;
        try{
            out.write("\n\n--\n-- Table structure for table `" + table + "`\n--\n\n");
            Statement s = conn.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            s.executeQuery ("SHOW CREATE TABLE " + table);
            ResultSet rs = s.getResultSet ();
            while (rs.next ())
            {
                createTable = rs.getString("Create Table") + ";";
            }
        } catch (SQLException e) {

        } catch(IOException e){
            System.err.println (e.getMessage());
        }
        return createTable;
    }

    public void dumpTable(BufferedWriter out, String table){
         try{
            Statement s = conn.createStatement (ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
            out.write("\n\n--\n-- Dumping data for table `" + table + "`\n--\n\n");
            s.executeQuery ("SELECT /*!40001 SQL_NO_CACHE */ * FROM " + table);
            ResultSet rs = s.getResultSet ();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            int columnCount = rsMetaData.getColumnCount();
            String prefix = new String("INSERT INTO " + table + " (");
            for (int i = 1; i <= columnCount; i++) {
                if (i == columnCount){
                    prefix += rsMetaData.getColumnName(i) + ") VALUES(";
                }else{
                    prefix += rsMetaData.getColumnName(i) + ",";
                }
            }
            String postfix = new String();
            int count = 0;
            while (rs.next ())
            {

                postfix = "";
                for (int i = 1; i <= columnCount; i++) {
                    if (i == columnCount){
                        System.err.println(rs.getMetaData().getColumnClassName(i));
                        postfix += "'" + rs.getString(i) + "');\n";
                    }else{

                        System.err.println(rs.getMetaData().getColumnTypeName(i));
                        if (rs.getMetaData().getColumnTypeName(i).equalsIgnoreCase("LONGBLOB")){
                            try{
                                postfix += "'" + escapeString(rs.getBytes(i)).toString() + "',";
                            }catch (Exception e){
                                postfix += "NULL,";
                            }
                        }else{
                            try{
                                postfix += "'" + rs.getString(i).replaceAll("\n","\\\\n").replaceAll("'","\\\\'") + "',";
                            }catch (Exception e){
                                postfix += "NULL,";
                            }
                    }   }
                }
                out.write(prefix + postfix + "\n");
                ++count;
            }
            rs.close ();
            s.close();
        }catch(IOException e){
            System.err.println (e.getMessage());
        }catch(SQLException e){
            System.err.println (e.getMessage());
        }
    }

    public File dumpAllViews(String database) {
        return null;
    }

    public String dumpCreateView(String view) {
        return null;
    }

    public File dumpView(String view) {
        return null;
    }

    /**
    * Escape string ready for insert via mysql client
    *
    * @param  bIn       String to be escaped passed in as byte array
    * @return bOut      MySQL compatible insert ready ByteArrayOutputStream
    */
    private ByteArrayOutputStream escapeString(byte[] bIn){
        int numBytes = bIn.length;
        ByteArrayOutputStream bOut = new ByteArrayOutputStream(numBytes+ 2);
        for (int i = 0; i < numBytes; ++i) {
            byte b = bIn[i];

            switch (b) {
            case 0: /* Must be escaped for 'mysql' */
                    bOut.write('\\');
                    bOut.write('0');
                    break;

            case '\n': /* Must be escaped for logs */
                    bOut.write('\\');
                    bOut.write('n');
                    break;

            case '\r':
                    bOut.write('\\');
                    bOut.write('r');
                    break;

            case '\\':
                    bOut.write('\\');
                    bOut.write('\\');

                    break;

            case '\'':
                    bOut.write('\\');
                    bOut.write('\'');

                    break;

            case '"': /* Better safe than sorry */
                    bOut.write('\\');
                    bOut.write('"');
                    break;

            case '\032': /* This gives problems on Win32 */
                    bOut.write('\\');
                    bOut.write('Z');
                    break;

            default:
                    bOut.write(b);
            }
        }
        return bOut;
    }

    private String getHeader(){
        //return Dump Header
        return "-- BinaryStor MySQL Dump " + version + "\n--\n-- Host: " + hostname + "    " + "Database: " + database + "\n-- ------------------------------------------------------\n-- Server Version: " + databaseProductVersion + "\n--";
    }

    /**
    * Main entry point for MySQLDump when run from command line
    *
    * @param  args  Command line arguments
    */
    public static void main (String[] args) throws IOException {
        new MySQLDump().doMain(args);
    }

    /**
    * Parse command line arguments and run MySQLDump
    *
    * @param  args  Command line arguments
    */
    public void doMain(String[] args) throws IOException {

        String usage = "Usage: java -jar MySQLDump.jar [OPTIONS] database [tables]\nOR     java -jar MySQLDump.jar [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]\nOR     java -jar MySQLDump.jar [OPTIONS] --all-databases [OPTIONS]\nFor more options, use java -jar MySQLDump.jar --help";
        CmdLineParser parser = new CmdLineParser(this);

        // if you have a wider console, you could increase the value;
        // here 80 is also the default
        parser.setUsageWidth(80);

        try {
            // parse the arguments.
            parser.parseArgument(args);

            if (help) {
                throw new CmdLineException("Print Help");
            }

            // after parsing arguments, you should check
            // if enough arguments are given.
            if( arguments.isEmpty() )
                throw new CmdLineException("No argument is given");

        } catch( CmdLineException e ) {
            if (e.getMessage().equalsIgnoreCase("Print Help")){
                System.err.println("MySQLDump.java Ver " + version + "\nThis software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the BSD license" + "\n\n" + usage);
                return;
            }
            // if there's a problem in the command line,
            // you'll get this exception. this will report
            // an error message.
            System.err.println(e.getMessage());
            // print usage.
            System.err.println(usage);
            return;
        }

        //Do we have a hostname? if not use localhost as default
        if (hostname == null){
            hostname = "localhost";
        }
        //First argument here should be database
        database = arguments.remove(0);

        try{
            //Create temporary file to hold SQL output.
            File temp = File.createTempFile(database, ".sql");
            BufferedWriter out = new BufferedWriter(new FileWriter(temp));
            this.connect(hostname, username, password, database);
            out.write(getHeader());
            for( String arg : arguments )
                System.out.println(arg);
            out.write(dumpCreateTable(out,"blobdump"));
            this.dumpTable(out,"blobdump");
            out.close();
            this.cleanup();
        }
        catch (SQLException se){
            System.err.println (se.getMessage());
        }
    }

    public int cleanup(){
        try
        {
            conn.close ();
            System.out.println ("Database connection terminated");
        }
        catch (Exception e) { /* ignore close errors */ }
        return 1;
    }

}

WordPress server URL for offline interaction

Saturday, March 29th, 2008

Since I keep forgetting it;

http://server_root_path/xmlrpc/
or
http://server_root_path/xmlrpc.php