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

📄 monetconnection.java

📁 这个是内存数据库的客户端
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	 * Response look like:	 * <pre>	 * &amp;1 1 28 2 10	 * # name,     value # name	 * # varchar,  varchar # type	 * </pre>	 * there the first line consists out of<br />	 * <tt>&amp;"qt" "id" "tc" "cc" "rc"</tt>.	 */	// {{{ ResultSetResponse class implementation	class ResultSetResponse implements Response {		/** The number of columns in this result */		public final int columncount;		/** The total number of rows this result set has */		public final int tuplecount;		/** The numbers of rows to retrieve per DataBlockResponse */		private int cacheSize;		/** The table ID of this result */		public final int id;		/** The names of the columns in this result */		private String[] name;		/** The types of the columns in this result */		private String[] type;		/** The max string length for each column in this result */		private int[] columnLengths;		/** The table for each column in this result */		private String[] tableNames;		/** The query sequence number */		private final int seqnr;		/** A List of result blocks (chunks of size fetchSize/cacheSize) */		private DataBlockResponse[] resultBlocks;		/** A bitmap telling whether the headers are set or not */		private boolean[] isSet;		/** Whether this Response is closed */		private boolean closed;		/** The Connection that we should use when requesting a new block */		private MonetConnection.ResponseList parent;		/** Whether the fetchSize was explitly set by the user */		private boolean cacheSizeSetExplicitly = false;		/** Whether we should send an Xclose command to the server		 *  if we close this Response */		private boolean destroyOnClose;		/** the offset to be used on Xexport queries */		private int blockOffset = 0;		private final static int NAMES	= 0;		private final static int TYPES	= 1;		private final static int TABLES	= 2;		private final static int LENS	= 3;		/**		 * Sole constructor, which requires a MonetConnection parent to		 * be given.		 *		 * @param id the ID of the result set		 * @param tuplecount the total number of tuples in the result set		 * @param columncount the number of columns in the result set		 * @param rowcount the number of rows in the current block		 * @param parent the parent that created this Response and will		 *               supply new result blocks when necessary		 * @param seq the query sequence number		 */		ResultSetResponse(			int id,			int tuplecount,			int columncount,			int rowcount,			MonetConnection.ResponseList parent,			int seq)			throws SQLException		{			isSet = new boolean[7];			this.parent = parent;			if (parent.cachesize == 0) {				cacheSize = MonetConnection.DEF_FETCHSIZE;				cacheSizeSetExplicitly = false;			} else {				cacheSize = parent.cachesize;				cacheSizeSetExplicitly = true;			}			seqnr = seq;			closed = false;			destroyOnClose = false;			this.id = id;			this.tuplecount = tuplecount;			this.columncount = columncount;			this.resultBlocks =				new DataBlockResponse[(tuplecount / cacheSize) + 1];			resultBlocks[0] = new DataBlockResponse(				rowcount,				parent.rstype == ResultSet.TYPE_FORWARD_ONLY			);		}		/**		 * Parses the given string and changes the value of the matching		 * header appropriately, or passes it on to the underlying		 * DataResponse.		 *		 * @param tmpLine the string that contains the header		 * @return a non-null String if the header cannot be parsed or		 *         is unknown		 */		// {{{ addLine		public String addLine(String tmpLine, int linetype) {			if (isSet[LENS] && isSet[TYPES] &&					isSet[TABLES] && isSet[NAMES])			{				return(resultBlocks[0].addLine(tmpLine, linetype));			}			if (linetype != MonetSocketBlockMode.HEADER)				return("header expected, got: " + tmpLine);			char[] chrLine = tmpLine.toCharArray();			int len = chrLine.length;			int pos = 0;			boolean foundChar = false;			boolean nameFound = false;			// find header name			for (int i = len - 1; i >= 0; i--) {				switch (chrLine[i]) {					case ' ':					case '\n':					case '\t':					case '\r':						if (!foundChar) {							len = i - 1;						} else {							pos = i + 1;						}					break;					case '#':						// found!						nameFound = true;						if (pos == 0) pos = i + 1;						i = 0;	// force the loop to terminate					break;					default:						foundChar = true;						pos = 0;					break;				}			}			if (!nameFound)				return("illegal header: " + tmpLine);			// depending on the name of the header, we continue			switch (chrLine[pos]) {				default:					return("protocol violation: unknown header: " +							(new String(chrLine, pos, len - pos)));				case 'n':					if (len - pos == 4 &&							tmpLine.regionMatches(pos + 1, "name", 1, 3))					{						name = getValues(chrLine, 2, pos - 3);						isSet[NAMES] = true;					} else {						return("protocol violation: unknown header: " +								(new String(chrLine, pos, len - pos)));					}				break;				case 'l':					if (len - pos == 6 &&							tmpLine.regionMatches(pos + 1, "length", 1, 5))					{						try {							columnLengths = getIntValues(chrLine, 2, pos - 3);							isSet[LENS] = true;						} catch (SQLException e) {							return(e.getMessage());						}					} else {						return("protocol violation: unknown header: " +								(new String(chrLine, pos, len - pos)));					}				break;				case 't':					if (len - pos == 4 &&							tmpLine.regionMatches(pos + 1, "type", 1, 3))					{						type = getValues(chrLine, 2, pos - 3);						isSet[TYPES] = true;					} else if (len - pos == 10 &&							tmpLine.regionMatches(pos + 1, "table_name", 1, 9))					{						tableNames = getValues(chrLine, 2, pos - 3);						isSet[TABLES] = true;					} else {						return("protocol violation: unknown header: " +								(new String(chrLine, pos, len - pos)));					}				break;			}			// all is well			return(null);		}		// }}}		/**		 * Returns whether this ResultSetResponse needs more lines.		 * This method returns true if not all headers are set, or the		 * first DataBlockResponse reports to want more.		 */		public boolean wantsMore() {			if (isSet[LENS] && isSet[TYPES] &&					isSet[TABLES] && isSet[NAMES])			{				return(resultBlocks[0].wantsMore());			} else {				return(true);			}		}		/**		 * Returns an array of Strings containing the values between		 * ',\t' separators.		 *		 * @param chrLine a character array holding the input data		 * @param start where the relevant data starts		 * @param stop where the relevant data stops		 * @return an array of Strings		 */		final private String[] getValues(char[] chrLine, int start, int stop) {			int elem = 0;			String[] values = new String[columncount];						for (int i = start; i < stop; i++) {				if (chrLine[i] == '\t' && chrLine[i - 1] == ',') {					values[elem++] =						new String(chrLine, start, i - 1 - start);					start = i + 1;				}			}			// at the left over part			values[elem++] = new String(chrLine, start, stop - start);			return(values);		}		/**		 * Returns an array of ints containing the values between		 * ',\t' separators.		 *		 * @param chrLine a character array holding the input data		 * @param start where the relevant data starts		 * @param stop where the relevant data stops		 * @return an array of ints		 */		final private int[] getIntValues(				char[] chrLine,				int start,				int stop			) throws SQLException		{			int elem = 0;			int tmp = 0;			int[] values = new int[columncount];			try {				for (int i = start; i < stop; i++) {					if (chrLine[i] == ',' && chrLine[i + 1] == '\t') {						values[elem++] = tmp;						tmp = 0;						start = ++i;					} else {						tmp *= 10;						tmp += MonetResultSet.getIntrinsicValue(chrLine[i], i);					}				}				// at the left over part				values[elem++] = tmp;			} catch (java.text.ParseException e) {				throw new SQLException(e.getMessage() +						" found: '" + chrLine[e.getErrorOffset()] + "'" +						" in: " + new String(chrLine) +						" at pos: " + e.getErrorOffset());			}			return(values);		}		/**		 * Returns an the first String that appears before the first		 * occurrence of the ',\t' separator.		 *		 * @param chrLine a character array holding the input data		 * @param start where the relevant data starts		 * @param stop where the relevant data stops		 * @return the first String found		 */		private final String getValue(char[] chrLine, int start, int stop) {			for (int i = start; i < stop; i++) {				if (chrLine[i] == '\t' && chrLine[i - 1] == ',') {					return(new String(chrLine, start, i - 1 - start));				}			}			return(new String(chrLine, start, stop - start));		}		/**		 * Adds the given DataBlockResponse to this ResultSetResponse at		 * the given block position.		 *		 * @param offset the offset number of rows for this block		 * @param rr the DataBlockResponse to add		 */		void addDataBlockResponse(int offset, DataBlockResponse rr) {			int block = (offset - blockOffset) / cacheSize;			resultBlocks[block] = rr;		}		/**		 * Marks this Response as being completed.  A complete Response		 * needs to be consistent with regard to its internal data.		 *		 * @throws SQLException if the data currently in this Response is not		 *                      sufficient to be consistant		 */		public void complete() throws SQLException {			String error = "";			if (!isSet[NAMES]) error += "name header missing\n";			if (!isSet[TYPES]) error += "type header missing\n";			if (!isSet[TABLES]) error += "table name header missing\n";			if (!isSet[LENS]) error += "column width header missing\n";			if (error != "") throw new SQLException(error);		}		/**		 * Returns the names of the columns		 *		 * @return the names of the columns		 */		String[] getNames() {			return(name);		}		/**		 * Returns the types of the columns		 *		 * @return the types of the columns		 */		String[] getTypes() {			return(type);		}		/**		 * Returns the tables of the columns		 *		 * @return the tables of the columns		 */		String[] getTableNames() {			return(tableNames);		}		/**		 * Returns the lengths of the columns		 *		 * @return the lengths of the columns		 */		int[] getColumnLengths() {			return(columnLengths);		}		/**		 * Returns the cache size used within this Response		 *		 * @return the cache size		 */		int getCacheSize() {			return(cacheSize);		}		/**		 * Returns the current block offset		 *		 * @return the current block offset		 */		int getBlockOffset() {			return(blockOffset);		}		/**		 * Returns the ResultSet type, FORWARD_ONLY or not.		 *		 * @return the ResultSet type		 */		int getRSType() {			return(parent.rstype);		}		/**		 * Returns the concurrency of the ResultSet.		 *		 * @return the ResultSet concurrency		 */		int getRSConcur() {			return(parent.rsconcur);		}		/**		 * Returns a line from the cache. If the line is already present in the		 * cache, it is returned, if not apropriate actions are taken to make		 * sure the right block is being fetched and as soon as the requested		 * line is fetched it is returned.		 *		 * @param row the row in the result set to return

⌨️ 快捷键说明

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