package com.quantum.sql;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.quantum.model.Bookmark;
import com.quantum.model.Entity;


/**
 * @author BC
 */
public class SQLMetaDataResults extends SQLResultSetResults {

	/**
	 * @param query
	 */
	private SQLMetaDataResults(String query, Bookmark bookmark, Entity entity) {
		super(query, bookmark, entity);
	}

	static SQLResultSetResults create(Bookmark bookmark, ResultSet set, String query, Entity entity) throws SQLException {

		SQLMetaDataResults results = new SQLMetaDataResults(query, bookmark, entity);
		results.parseResultSet(set);
		
		return results;
	}
	
	/**
	 * @param set
	 * @param results
	 * @param metaData
	 * @param columnCount
	 * @throws SQLException
	 */
	protected void parseResultSet(ResultSet set) throws SQLException {

		List columns = new ArrayList();
		columns.add(new Column("ColumnName", "", 0)); //$NON-NLS-1$
		columns.add(new Column("Type Name", "", 0)); //$NON-NLS-1$
		columns.add(new Column("Size", "", 0)); //$NON-NLS-1$
		columns.add(new Column("Scale", "", 0)); //$NON-NLS-1$
		columns.add(new Column("Nullable", "", 0)); //$NON-NLS-1$
		columns.add(new Column("AutoIncrement", "", 0)); //$NON-NLS-1$
		columns.add(new Column("Type", "", 0)); //$NON-NLS-1$
		setColumns((Column[]) columns.toArray(new Column[columns.size()]));
		
		ResultSetMetaData metaData = set.getMetaData();
		
		List rowList = new ArrayList();
		for (int i = 1; i <= metaData.getColumnCount(); i++) {
			Vector row = new Vector();
			row.addElement(metaData.getColumnName(i));
			row.addElement(metaData.getColumnTypeName(i));
			long precision = 0;
			try {
				precision = metaData.getPrecision(i);
            } catch (Throwable t) {
            	// Do nothing. An exception can be generated by some very large row sizes, like BLOB in Oracle.
            	// Then getPrecision() will generate an exception. So we ignore it and go on.
            }
			if (precision == 0) {
				precision = metaData.getColumnDisplaySize(i);
			}
			int scale = metaData.getScale(i);
			
			row.addElement(new Long(precision));
			row.addElement(new Integer(scale));
			
			int nullable = metaData.isNullable(i);
			if (nullable == ResultSetMetaData.columnNoNulls) {
				row.addElement("Not Null"); //$NON-NLS-1$
			} else if (nullable == ResultSetMetaData.columnNullable) {
				row.addElement("Nullable"); //$NON-NLS-1$
			} else if (
				nullable == ResultSetMetaData.columnNullableUnknown) {
				row.addElement("Nullable"); //$NON-NLS-1$
			} else {
				row.addElement("<Error>"); //$NON-NLS-1$
			}
			row.addElement(
				(metaData.isAutoIncrement(i)
					? Boolean.TRUE
					: Boolean.FALSE)
					.toString());
			rowList.add(new Row(row));
			row.addElement(new Integer(metaData.getColumnType(i)));
		}
		setRows((Row[]) rowList.toArray(new Row[rowList.size()]));
	}

	public boolean isMetaData() {
		return true;
	}
}