 /*
 * Copyright (C) 09-sept.-2003  Jean-Yves Beaujean 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,  59
 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 
 */
package jxtray.dump;

import java.sql.ResultSet;
import java.sql.Statement;

import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Connection;

import jxtray.util.SQLUtilities;
import jxtray.util.TimeUtilities;

import jxtray.Jxtray;


import jxtray.io.WriterContext;

/** This class dump data in SQL format.
 * 
*/
public class JxtSQLDumpStrategy extends JxtDumpStrategy implements Runnable 
{
	
	
	
	public JxtSQLDumpStrategy(String filename,DumperListener listener,Connection connection,String lib, String table, WriterContext writer)
	{
		super(filename,listener,connection,lib,table,writer);
	}
	
	public String getName() { return "SQL Dumper";}
	
	public void run()
	{
		_finished=false;
		try
		{
			double tstart = System.currentTimeMillis();
			dumpStructure();
			dumpData();
			double diff = System.currentTimeMillis()- tstart;
			_listener.dumpLog("\n"+Jxtray.getLang("dump.operation_time")+ TimeUtilities.smartTime(diff/1000) );
			_output.close();
		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		catch ( Error e )
		{
			_listener.dumpError(e.getMessage());
		}		
		_listener.dumpEnded();
		_finished=true;
		_thread=null;
	}
	
	protected void dumpData()
	{
		
		StringBuffer query = new StringBuffer();
		try
		{
			if ( _lib != null && _lib.length() > 0 )
					query.append("select * from ").append(_lib).append(".").append(_table);
			else
					query.append("select * from ").append(_table);		

			_listener.dumpLog("\n"+Jxtray.getLang("dump.execute_query")+query);
			_listener.dumpState(Jxtray.getLang("dump.select_datas"));
			Statement stmt =   _connection.createStatement();
			ResultSet res =stmt.executeQuery(query.toString());
			ResultSetMetaData rmtd =  res.getMetaData();
			StringBuffer record = null;
			while ( res.next())
			{
					_cpt++; 
					_listener.dumpNextRecord(_cpt);
					record = new StringBuffer();
					record.append("insert into ").append(_table).append(" values ( ");
					for ( int i = 0 ; i < rmtd.getColumnCount();i++)
					{
							
							if ( i > 0 )
								record.append(", ");
								
							int ctype = rmtd.getColumnType(i+1);
							if ( ctype == Types.CHAR || ctype == Types.LONGVARCHAR || ctype == Types.VARCHAR)
								record.append("'"+SQLUtilities.addSlashes(res.getString(i+1),_connection.getMetaData().getSearchStringEscape(),"'")).append("'");
							else if ( ctype == Types.DATE )
								record.append("'"+SQLUtilities.addSlashes(res.getString(i+1),_connection.getMetaData().getSearchStringEscape(),"'")).append("'");
							else
								record.append(" ").append(res.getString(i+1) );
					}
					record.append(");\n");
					_output.write(record.toString());
			}
			res.close();
			stmt.close();
		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		
		_listener.dumpLog("\n"+_cpt+Jxtray.getLang("dump.recordsdumped"));
		
	}
	
	protected void dumpStructure()
	{
		
		 StringBuffer dump = new StringBuffer();
		_listener.dumpState(Jxtray.getLang("dump.structure"));
		try
		{
				_output.write("CREATE TABLE "+_table+"\n(\n");
				
				java.sql.ResultSet res = _connection.getMetaData().getColumns(_lib,null,_table,null);
				java.sql.ResultSetMetaData rmtd = res.getMetaData();
				
				int cptRow = 0;
				StringBuffer field = null;
				while ( res.next() )
				{
					field = new StringBuffer();
					if ( cptRow == 0 )
						field.append("\t");
					else
						field.append("\t,");
					
					field.append(res.getString(4)).append(" ").append(res.getString(6)).append("(").append(res.getString(7)).append(")");
					if ( res.getInt(11) == ResultSetMetaData.columnNoNulls)
						field.append(" not null");
					field.append("\n");
					_output.write(field.toString());
					cptRow++;
				}
				_output.write(");\n\n");				
						res.close();
		}
		catch ( SQLException e )
		{
			_listener.dumpError(e.getMessage());
		}
		catch ( Exception e )
		{
			_listener.dumpError(e.getMessage());
		}
		
	}		
}
