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

📄 odbcmetadatagenerator.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * 	(SELECT T1.i, T1.j + T2.a, T2.a FROM T1, T2) VT	 *	 * Which specific columns are added to the subquery	 * depends on the query in question.	 *	 * @param queryName Name of the query in question.	 * @param subqueryText text of the subquery in question.	 * @param insertPos Index into the received buffer	 *	marking the position where the helper columns	 * 	should be inserted.	 */	private void addHelperColsToSubquery(String queryName,		StringBuffer subqueryText, int insertPos)	{		if (queryName.equals("getColumns")) {			subqueryText.insert(insertPos,				getFragment("GET_COLS_HELPER_COLS"));		}		else if (queryName.startsWith("getBestRowIdentifier")) {			subqueryText.insert(insertPos,				getFragment("BEST_ROW_ID_HELPER_COLS"));		}	}	/* ****	 * extractColName	 * Takes a single column definition from a SELECT clause	 * and returns only the unqualified name of the column.	 * Assumption here is that any column definition we see	 * here will either 1) end with an "AS <COLUMN_NAME>"	 * clause, or 2) consist of ONLY a column name, such	 * as "A" or "A.B".  At the time of writing, these	 * assumptions were true for all relevant metadata	 * queries.	 *	 * Ex. If colDef is "A", this method will return "A".	 * If colDef is "A.B", this method will return "B".	 * If colDef is "<bunch of SQL> AS C", this method	 * will return "C".	 *	 * @param colDef Column definition from which we're	 *	trying to extract the name.	 * @return Name of the column that is referenced in	 *	the received column definition.	 */	private String extractColName(String colDef) {		// Find out where the column name starts.		int pos = colDef.lastIndexOf("AS ");		if (pos == -1) {		// we assume that the col def is _just_ a column name,		// so start at the beginning.			pos = 0;		}		else {			// Move beyond the "AS".			pos += 2;			// Skip any non-important whitespace or backslashes.			char c = colDef.charAt(pos);			while ((c == '\\') || Character.isWhitespace(c))				c = colDef.charAt(++pos);		}		// Check to see if it's a qualified name.		int pos2 = colDef.indexOf(".", pos);		if (pos2 == -1)		// it's not a qualified name, so just return it.			return colDef.substring(pos, colDef.length());		// Else, strip off the schema and just return the col name.		return colDef.substring(pos2+1, colDef.length());	}	/* ****	 * getCastInfoForCol	 * Returns the target type for a result set column that	 * needs to be cast into an ODBC type.  This is usually	 * for casting integers to "SMALLINT".	 * @param queryName Name of query being processed.	 * @param colName Name of the specific column for which	 * 	we are trying to find the target type.	 * @return The target type if one exists, or else null	 *  if the received column in the received query has	 * 	no known target type.	 */	private String getCastInfoForCol(String queryName,		String colName)	{		if (queryName.equals("getTypeInfo")) {			if (colName.equals("NULLABLE") ||				colName.equals("CASE_SENSITIVE") ||				colName.equals("SEARCHABLE") ||				colName.equals("UNSIGNED_ATTRIBUTE") ||				colName.equals("FIXED_PREC_SCALE") ||				colName.equals("AUTO_UNIQUE_VAL") ||				colName.equals("SQL_DATA_TYPE") ||				colName.equals("SQL_DATETIME_SUB") ||				colName.equals("MINIMUM_SCALE") ||				colName.equals("MAXIMUM_SCALE"))			{				return "SMALLINT";			}		}		else if (queryName.equals("getColumns")) {			if (colName.equals("DECIMAL_DIGITS") ||				colName.equals("NULLABLE") ||				colName.equals("NUM_PREC_RADIX") ||				colName.equals("SQL_DATA_TYPE") ||				colName.equals("SQL_DATETIME_SUB"))			{				return "SMALLINT";			}		}		else if (queryName.equals("getVersionColumns")) {			if (colName.equals("SCOPE") ||				colName.equals("DATA_TYPE") ||				colName.equals("DECIMAL_DIGITS") ||				colName.equals("PSEUDO_COLUMN"))			{				return "SMALLINT";			}		}		else if (queryName.equals("getPrimaryKeys")) {			if (colName.equals("KEY_SEQ"))				return "SMALLINT";		}		else if (queryName.equals("getIndexInfo")) {			if (colName.equals("NON_UNIQUE") ||				colName.equals("TYPE") ||				colName.equals("ORDINAL_POSITION"))			{				return "SMALLINT";			}		}		// No target type for the received column		// in the received query (leave it unchanged).		return null;	}	/* ****	 * markNewColPosition	 * In effect, "marks" the position at which additional	 * columns are to be added for ODBC compliance.  This	 * is accomplished by adding a dummy column name to	 * the list of SELECT columns.  Later, in the method	 * that actually adds the columns, we'll do a find-	 * replace on this dummy value.	 * @param queryName Name of the query.	 * @param selectColDefs Array list of the SELECT	 * 	columns that exist in the ODBC version of	 *	the query thus far.	 * @return A dummy column name has been added to	 *	the received list of columns at the position	 *	at which new ODBC columns should be added.	 *  If a query doesn't require additional	 * 	columns to be ODBC compliant, this method	 *	leaves the received column list unchanged.	 */	private void markNewColPosition(String queryName,		ArrayList selectColDefs)	{		if (!stmtNeedsChange(queryName, ADD_COLUMN_CHANGE))			return;		if (queryName.equals("getProcedureColumns")) {		// Add the new columns in front of the Derby-specific ones.		// The "-2" in the next line is because there are 2 Derby-		// specific columns in the JDBC version of getProcedureCols		// (PARAMETER_ID and METHOD_ID).			selectColDefs.add(selectColDefs.size() - 2, NEW_COL_PLACEHOLDER);		}		else if (queryName.equals("getTypeInfo")) {		// just add the new column to the end.			selectColDefs.add(NEW_COL_PLACEHOLDER);		}	}	/* ****	 * addNewColumnsForODBC	 * Adds new columns to the ODBC version of a metadata	 * query (the ODBC version is at this point being	 * built up in newQueryText).  Before this method	 * was called, a dummy placeholder should have been	 * placed in the newQueryText buffer (by a call to	 * "markNewColPosition").  This method simply replaces	 * that dummy placeholder with the SQL text for the	 * new columns.	 * @param queryName Name of query being processed.	 * @newQueryText The buffer in which we want to	 * 	add the new column.	 * @return The dummy placeholder in the received	 *  buffer has been replaced with any ODBC columns	 *  that need to be added to the query in question	 *  for ODBC compliance.	 */	private void addNewColumnsForODBC(String queryName,		StringBuffer newQueryText)	{		if (!stmtNeedsChange(queryName, ADD_COLUMN_CHANGE))			return;		changeColValueToODBC(queryName, NEW_COL_PLACEHOLDER, newQueryText);		// It's possible that the new column fragments we added		// have placeholders in them for _other_ fragments.  We		// need to do the substitution here.		if (queryName.equals("getProcedureColumns")) {			fragSubstitution("SQL_DATA_TYPE_FOR_ODBC", newQueryText);			fragSubstitution("DATETIME_SUB_FOR_ODBC", newQueryText);		}		return;	}	/* ****	 * fragSubstitution	 * Replaces a single occurrence of the received	 * fragment key with the text corresponding to	 * that key.	 * @param fragKey The fragment key for which we are	 *	going to do the substitution.	 * @queryText The buffer in which we are going to do	 * 	the substitution.	 * @return fragKey has been substituted (IN PLACE)	 *	with the fragment corresponding to it in the	 *	received buffer.  If the fragment key could not	 * 	be found, the buffer remains unchanged.	 */	private void fragSubstitution(String fragKey,		StringBuffer queryText)	{		int pos = queryText.toString().indexOf(fragKey);		if (pos != -1) {			// NOTE: the " + 1" and " - 1" in the next line			// are needed because the fragment key is			// enclosed within curly braces ("{}").			queryText.replace(pos - 1, pos + fragKey.length() + 1,				getFragment(fragKey));		}	}	/* ****	 * readLine	 * Reads a line from the received input stream and stores it	 * into the received character array.  In this method, we	 * consider the end of the line to be either 1) "\n" char, or	 * 2) a single backslash "\", which is used in metadata	 * queries to indicate line continuation.  After reading	 * a line, we append an EOL to it for formatting purposes,	 * but that last EOL is NOT included in the count of	 * characters.	 * @param is The input stream from which we're reading.	 * @param line The char array into which we're reading.	 * @return the number of characters read from the	 *	stream; -1 if we reached end of the stream.	 */	private int readLine(InputStream is, char [] line)		throws IOException	{		int count = 0;		boolean atLeastOneNonWSChar = false;		char ch;		int byteRead;		for (byteRead = is.read();			(byteRead != -1) && (count < line.length);			byteRead = is.read())		{			ch = (char)byteRead;			line[count++] = ch;			atLeastOneNonWSChar = true;			if ((ch == '\\') || (ch == '\n'))				break;		}		if ((byteRead == -1) && (count == 0))		// end of file.			return -1;		// Take off trailing whitespace.		while ((count > 0) && Character.isWhitespace(line[count-1]))			count--;		// Add an EOL for ease of reading, but don't include it in		// "count" total.		line[count] = '\n';		return count;	}	/* ****	 * trimIgnorable	 * Removes all 'ignorable' chars that immediately precede or	 * follow (depending on the direction) the character at	 * the received index.  "Ignorable" here means whitespace	 * OR a single backslash ("\"), which is used in the	 * metadata.properties file to indicate line continuation.	 * @param direction +1 if we want to trim following, -1	 *	if we want to trim preceding.	 * @param chars The character array being processed.	 * @param index The point before/after which to start	 * 	trimming.	 * @return The index into the received char array of the	 *	"last" ignorable character w.r.t the received index	 *	and direction.  In other words, if we're trimming	 *	the chars FOLLOWING, the returned index will be of	 * 	the last (reading left-to-right) ignorable char; if	 *	we're trimming the chars PRECEDING, the returned index	 *	will be of the first (reading left-to-right) ignorable	 *	character.	 */	private int trimIgnorable(short direction, char [] chars, int index) {		index += direction;		while ((index >= 0) && (index < chars.length) &&			((chars[index] == '\\') ||			Character.isWhitespace(chars[index])))		{			index += direction;		}		// index is now on the final non-ignorable character		// in the given direction.  Move it back one so that		// it's on the "last" ignorable character (with		// respect to direction).		index -= direction;		return index;	}	/* ****	 * trimIgnorable	 * Same as trimIgnorable above, except with String argument	 * instead of char[].	 */	private int trimIgnorable(short direction, String str, int index) {		index += direction;		while ((index >= 0) && (index < str.length()) &&			((str.charAt(index) == '\\') ||			Character.isWhitespace(str.charAt(index))))		{			index += direction;		}		// index is now on the final non-ignorable character		// in the given direction.  Move it back one so that		// it's on the "first" ignorable character (with		// respect to direction).		index -= direction;		return index;	}	/* ****	 * stmtNeedsChange	 * Returns whether or not a specific metadata statement	 * requires the received type of change.  This is determined	 * based on the info stored in the "changeMaps" mapping.	 * @param queryName Name of the query in question.	 * @param changeType The type of change in question.	 */	private boolean stmtNeedsChange(String queryName, byte changeType) {		Byte changeByte = (Byte)changeMap.get(queryName);		if (changeByte == null)		// No entry means change is not needed.			return false;		return ((changeByte.byteValue() & changeType) == changeType);	}	/* ****	 * getFragment	 * Looks up an SQL fragment and returns the value as a String.	 * @param String fragId id of the fragment to look up.	 * @return The string fragment corresponding to the received	 * 	fragment id.	 */	private String getFragment(String fragId) {		return (String)(odbcFragments.get(fragId));	}	}

⌨️ 快捷键说明

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