⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mclresultset.java

📁 这个是内存数据库的客户端
💻 JAVA
字号:
/* * The contents of this file are subject to the MonetDB Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * The Original Code is the MonetDB Database System. * * The Initial Developer of the Original Code is CWI. * Portions created by CWI are Copyright (C) 1997-2007 CWI. * All Rights Reserved. */package nl.cwi.monetdb.mcl;import nl.cwi.monetdb.mcl.messages.*;import java.util.*;import java.lang.reflect.Array; // for dealing with the anonymous columns/** * An MCLResultSet is a container for tabular data.  An MCLServer * instance uses this oject to generate a HeaderMessage and DataMessages * as appropriately.  An MCLResultSet can store a number of 'columns' * and their metadata.  Each column stored in an MCLResultSet must have * an equal number of values (tuples). * * Note: this class is the equivalent of the rsbox in MonetDB/Five. * * @author Fabian Groffen <Fabian.Groffen@cwi.nl> */public class MCLResultSet {	private boolean isValid;	private List columns;	private String id;	private static int idcnt = 0;		/**	 * Creates a new MCLResultSet that is in intially empty.  An empty	 * MCLResultSet is not valid when being supplied to an MCLServer.	 */	public MCLResultSet() {		isValid = false;		columns = new ArrayList();		// we can't generate the id inline if we want to be thread safe		id = generateId();	}	/**	 * Retrieves the next id for an MCLResultSet.  This method is	 * synchronised to avoid race conditions when determining its id	 * from idcnt.	 *	 * @return the next id	 */	private synchronized String generateId() {		return("rs" + idcnt++);	}		/**	 * Adds the given Object array as column to this MCLResultSet.	 *	 * @param values the column values to add	 * @throws MCLException if this MCLResultSet was already marked	 *         valid	 */	public void addColumn(Object[] values) throws MCLException {		if (isValid) throw			new MCLException("Cannot append to a valid ResultSet");		columns.add(new Column(values));	}		/**	 * Checks and marks whether this MCLResultSet is valid.  An	 * MCLResultSet is considered to be valid if:	 * <ul>	 * <li>there is at least one column</li>	 * <li>all columns are of equal length</li>	 * </ul>	 * Note that if this method is called on an already valid	 * MCLResultSet, this method returns directly.	 *	 * @throws MCLException if one of the conditions described above is	 *         not met	 */	public void setValid() throws MCLException {		if (isValid) return;		if (columns.size() == 0) throw			new MCLException("This MCLResultSet has no columns yet");		int lastLength = -1, thisLength;		for (Iterator it = columns.iterator(); it.hasNext(); ) {			thisLength = Array.getLength(it.next());			if (lastLength == -1) lastLength = thisLength;			if (thisLength != lastLength) throw				new MCLException("Not all columns are of equal length " +						"(" + lastLength + "/" + thisLength + ")");		}		isValid = true;	}	/**	 * Returns whether this MCLResultSet is valid.	 *	 * @return true if this MCLResultset is valid, false otherwise	 */	public boolean isValid() {		return(isValid);	}	/**	 * Returns the id for this MCLResultSet.	 *	 * @return the id	 */	public String getId() {		return(id);	}	/**	 * Retrieves the metadata contained in this MCLResultSet as	 * HeaderMessage.  If this MCLResultSet is not valid, an	 * MCLException is thrown.	 *	 * @return a HeaderMessage populated with the metadata stored in	 *         this MCLResultSet	 * @throws MCLException if this MCLResultSet is not (yet) valid	 */	public HeaderMessage getHeaderMessage() throws MCLException {		if (!isValid) throw			new MCLException("MCLResultSet should be valid");		String ctype = "";		for (int i = 0; i < columns.size(); i++)			ctype += ((Column)(columns.get(i))).ctype;		HeaderMessage ret = new HeaderMessage(				id,				columns.size(),				((Column)(columns.get(0))).data.length,				ctype		);		String tmpS[] = new String[columns.size()];		for (int i = 0; i < columns.size(); i++)			tmpS[i] = ((Column)(columns.get(0))).column;		ret.addColumn(tmpS);		for (int i = 0; i < columns.size(); i++)			tmpS[i] = ((Column)(columns.get(0))).schema;		ret.addSchema(tmpS);		for (int i = 0; i < columns.size(); i++)			tmpS[i] = ((Column)(columns.get(0))).table;		ret.addTable(tmpS);		for (int i = 0; i < columns.size(); i++)			tmpS[i] = ((Column)(columns.get(0))).type;		ret.addTypes(tmpS);		int tmpI[] = new int[columns.size()];		for (int i = 0; i < columns.size(); i++)			tmpI[i] = ((Column)(columns.get(0))).digits;		ret.addDigits(tmpI);		for (int i = 0; i < columns.size(); i++)			tmpI[i] = ((Column)(columns.get(0))).scale;		ret.addScale(tmpI);		for (int i = 0; i < columns.size(); i++)			tmpI[i] = ((Column)(columns.get(0))).width;		ret.addWidth(tmpI);				return(ret);	}	/**	 * Retrieves a DataMessage for the given index position range.  If	 * the start or stop positions are out of the possible range an	 * MCLException is thrown.	 *	 * @param start the index position to start at, inclusive	 * @param stop the index position to stop at, exclusive	 * @throws MCLException if this MCLResultSet is not (yet) valid, or	 *         start and/or stop are out of range.	 */	public DataMessage getDataMessage(int start, int stop)		throws MCLException	{		int dataSize = ((Column)(columns.get(0))).data.length;		if (start >= dataSize || start < 0) throw			new MCLException("start index either too small or too large (0 <= " + start + " < " + dataSize + ")");		if (stop > dataSize || stop <= 0) throw			new MCLException("stop index either too small or too large (0 < " + stop + " <= " + dataSize + ")");		DataMessage ret = new DataMessage(stop - start);		StringBuffer tmpS = new StringBuffer(columns.size() * 20);		for ( ; start < stop; start++) {			for (int i = 0; i < columns.size(); i++) {				Column col = (Column)(columns.get(i));				switch (col.ctype) {					case 'B':						tmpS.append(((Boolean)(col.data[i])).booleanValue() ? '1' : '0');					break;					case 'c':						tmpS.append(((Character)(col.data[i])).charValue());					break;					case 'S':						tmpS.append(col.data[i].toString().length());						tmpS.append(':');						tmpS.append(col.data[i]);					break;					case 'o':						// not known (yet?)						tmpS.append("");					break;					case 'b':					case 's':					case 'i':						tmpS.append(((Number)(col.data[i])).intValue());					break;					case 'l':						tmpS.append(((Number)(col.data[i])).longValue());					break;					case 'f':					case 'd':						tmpS.append(col.data[i]);					break;					case 'L':						// not (yet?) supported						tmpS.append("");					break;					case 'T':					{						long millis = ((java.util.Date)(col.data[i])).getTime();						Calendar cal = Calendar.getInstance();						cal.setTime((java.util.Date)(col.data[i]));						int zone = -(cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000);						tmpS.append(prefixZero(millis / 1000, 10));						tmpS.append(prefixZero(millis % 1000 * 10, 7));						tmpS.append(zone < 0 ? '-' : '+');						tmpS.append(prefixZero(zone < 0 ? -zone : zone, 5));					}					break;					case 't':					{						long millis = ((java.sql.Time)(col.data[i])).        getTime();						Calendar cal = Calendar.getInstance();						cal.setTime((java.sql.Time)(col.data[i]));						int zone = -(cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000);						tmpS.append(prefixZero(millis / 1000, 5));						tmpS.append(zone < 0 ? '-' : '+');						tmpS.append(prefixZero(zone < 0 ? -zone : zone, 5));					}					break;					case 'D':					{						long millis = ((java.sql.Date)(col.data[i])).getTime();						tmpS.append(prefixZero(millis / 1000, 10));					}					break;					case 'u':					{						String clazz = col.data[i].getClass().getName();						clazz = clazz.substring(clazz.lastIndexOf(".") + 1);						tmpS.append(clazz);						tmpS.append(':');						tmpS.append(col.data[i].toString().length());						tmpS.append(':');						tmpS.append(col.data[i]);					}					break;				}				if (i < columns.size() - 1) tmpS.append('\t');			}			ret.addSentence(new MCLSentence(MCLSentence.DATA, tmpS.toString()));			tmpS.delete(0, tmpS.length());		}		return(ret);	}	/**	 * Utility function that returns the given numerical object prefixed	 * with as much zeroes as necessary to return a String of the	 * desired length.	 *	 * @param num the numerical object	 * @param len the desired length	 * @return a String of length len representing the numerical object	 */	private String prefixZero(long num, int len) throws MCLException {		if (num < 0) throw			new MCLException("Negative values not supported");		StringBuffer ret = new StringBuffer(len);		ret.append("" + num);		if (ret.length() > len) throw			new MCLException("Given value does not fit in the desired length");		while (ret.length() < len) ret.insert(0, '0');		return(ret.toString());	}	/**	 * Small inner class that represents a column within an MCLResultSet	 * and its associated metadata.	 */	public class Column {		private Object[] data;		private char ctype;		private String column;		private String table;		private String schema;		private String type;		private int digits;		private int scale;		private int width;		/**		 * Constructs a new column using the given values.  For each		 * column added, the minimum required set of metadata is		 * automatically generated.		 *		 * @param data the values to populate the column with		 * @throws MCLException if data is null		 */		public Column(Object[] data) throws MCLException {			if (data == null) throw				new MCLException("Column values may not be absent");			this.data = data;			// set default values based on what we have			if (data instanceof Boolean[]) {				ctype = 'B';				type = "boolean";				width = 1; // either 0 or 1			} else if (data instanceof Character[]) {				ctype = 'c';				type = "char";				width = 1;			} else if (data instanceof String[]) {				ctype = 'S';				type = "varchar";				width = 0;				for (int i = 0; i < data.length; i++) {					if (width < data[i].toString().length())						width = data[i].toString().length();				}			} else if (data instanceof Byte[]) {				ctype = 'b';				type = "tinyint";				byte tmp = 0;				for (int i = 0; i < data.length; i++) {					if (tmp < ((Byte)(data[i])).byteValue())						tmp = ((Byte)(data[i])).byteValue();				}				width = 0;				while ((tmp /= 10) > 0) width++;			} else if (data instanceof Short[]) {				ctype = 's';				type = "smallint";				short tmp = 0;				for (int i = 0; i < data.length; i++) {					if (tmp < ((Short)(data[i])).shortValue())						tmp = ((Short)(data[i])).shortValue();				}				width = 0;				while ((tmp /= 10) > 0) width++;			} else if (data instanceof Integer[]) {				ctype = 'i';				type = "int";				int tmp = 0;				for (int i = 0; i < data.length; i++) {					if (tmp < ((Integer)(data[i])).intValue())						tmp = ((Integer)(data[i])).intValue();				}				width = 0;				while ((tmp /= 10) > 0) width++;			} else if (data instanceof Long[]) {				ctype = 'l';				type = "bigint";				long tmp = 0;				for (int i = 0; i < data.length; i++) {					if (tmp < ((Long)(data[i])).longValue())						tmp = ((Long)(data[i])).longValue();				}				width = 0;				while ((tmp /= 10) > 0) width++;			} else if (data instanceof Float[]) {				ctype = 'f';				type = "real";				width = 12; // SQL99 max			} else if (data instanceof Double[]) {				ctype = 'd';				type = "double";				width = 24; // SQL99 max			} else if (data instanceof java.sql.Timestamp[] ||					data instanceof java.util.Date[]) {				ctype = 'T';				type = "timestampz";				width = 22;			} else if (data instanceof java.sql.Time[]) {				ctype = 't';				type = "timez";				width = 11;			} else if (data instanceof java.sql.Date[]) {				ctype = 'D';				type = "date";				width = 10;			} else {				ctype = 'S';	// we map anything else to a String				type = "varchar";				width = 0;				for (int i = 0; i < data.length; i++) {					if (width < data[i].toString().length())						width = data[i].toString().length();				}			}			// name defaults to column_x			column = "column_" + this.hashCode();			table = null;			schema = null;			digits = -1;			scale = -1;		}		/**		 * Sets the column name for this column.		 *		 * @param name the column name		 */		public void setColumnName(String name) {			column = name;		}		/**		 * Sets the table name for this column.		 *		 * @param name the table name		 */		public void setTableName(String name) {			table = name;		}		/**		 * Sets the schema name for this column.		 *		 * @param name the schema name		 */		public void setSchemaName(String name) {			schema = name;		}		/**		 * Sets the (SQL) type for this column.		 *		 * @param name the type name		 */		public void setType(String name) {			type = name;		}		/**		 * Sets the digits component for this column.		 *		 * @param num the number of digits		 */		public void setDigits(int num) {			digits = num;		}		/**		 * Sets the scale component for this column.		 *		 * @param num the number of scale digits		 */		public void setScale(int num) {			scale = num;		}		/**		 * Sets the (character) width for this column.		 *		 * @param num the character width		 */		public void setWidth(int num) {			width = num;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -