jdbcclient.java

来自「这个是内存数据库的客户端」· Java 代码 · 共 1,234 行 · 第 1/3 页

JAVA
1,234
字号
			// we want nice table views			e.setProperty(SQLExporter.TYPE_OUTPUT, SQLExporter.VALUE_TABLE);		}		e.useSchemas(false);		try {			// use the given file for reading			boolean hasFile = copts.getOption("file").isPresent();			boolean doEcho = hasFile && copts.getOption("echo").isPresent();			if (hasFile) {				String tmp = copts.getOption("file").getArgument();				int batchSize = 0;				try {					in = getReader(tmp);				} catch (Exception e) {					System.err.println("Error: " + e.getMessage());					System.exit(-1);				}				// check for batch mode				oc = copts.getOption("Xbatching");				if (oc.isPresent()) {					if (oc.getArgumentCount() == 1) {						// parse the number						try {							batchSize = Integer.parseInt(oc.getArgument());						} catch (NumberFormatException ex) {							// complain to the user							throw new IllegalArgumentException("Illegal argument for Xbatching: " + oc.getArgument() + " is not a parseable number!");						}					}					processBatch(batchSize);				} else {					processInteractive(true, doEcho, scolonterm, user);				}			} else {				if (!copts.getOption("quiet").isPresent()) {					// print welcome message					out.println("Welcome to the MonetDB interactive JDBC terminal!");					if (dbmd != null) {						out.println("Database: " + dbmd.getDatabaseProductName() + " " +							dbmd.getDatabaseProductVersion());						out.println("Driver: " + dbmd.getDriverName() + " " +							dbmd.getDriverVersion());					}					out.println("Type \\q to quit, \\h for a list of available commands");					out.flush();				}				processInteractive(false, doEcho, scolonterm, user);			}			// free resources, close the statement			stmt.close();			// close the connection with the database			con.close();			// close the file (if we used a file)			in.close();		} catch (Exception e) {			System.err.println("A fatal exception occurred: " + e.toString());			e.printStackTrace(System.err);			// at least try to close the connection properly, since it will			// close all statements associated with it			try {				con.close();			} catch (SQLException ex) {				// ok... nice try			}			System.exit(-1);		}	}	/**	 * Tries to interpret the given String as URL or file.  Returns the	 * assigned BufferedReader, or throws an Exception if the given	 * string couldn't be identified as a valid URL or file.	 *	 * @param uri URL or filename as String	 * @return a BufferedReader for the uri	 * @throws Exception if uri cannot be identified as a valid URL or	 *         file	 */	static BufferedReader getReader(String uri) throws Exception {		BufferedReader ret = null;		URL u = null;		// Try and parse as URL first		try {			u = new URL(uri);		} catch (MalformedURLException e) {			// no URL, try as file			try {				ret = new BufferedReader(new FileReader(uri));			} catch (FileNotFoundException fnfe) {				// the message is descriptive enough, adds "(No such file				// or directory)" itself.				throw new Exception(fnfe.getMessage());			}		}		if (ret == null) try {			HttpURLConnection.setFollowRedirects(true);			HttpURLConnection con =				(HttpURLConnection)u.openConnection();			con.setRequestMethod("GET");			String ct = con.getContentType();			if ("application/x-gzip".equals(ct)) {				// open gzip stream				ret = new BufferedReader(new InputStreamReader(							new GZIPInputStream(con.getInputStream())));			} else {				// text/plain otherwise just attempt to read as is				ret = new BufferedReader(new InputStreamReader(							con.getInputStream()));			}		} catch (IOException e) {			// failed to open the url			throw new Exception("No such host: " + e.getMessage());		} catch (Exception e) {			// this is an exception that comes from deep ...			throw new Exception("Invalid URL: " + e.getMessage());		}		return(ret);	}	/**	 * Starts an interactive processing loop, where output is adjusted to an	 * user session.  This processing loop is not suitable for bulk processing	 * as in executing the contents of a file, since processing on the given	 * input is done after each row that has been entered.	 *	 * @param hasFile a boolean indicating whether a file is used as input	 * @param doEcho a boolean indicating whether to echo the given input	 * @param user a String representing the username of the current user	 * @throws IOException if an IO exception occurs	 * @throws SQLException if a database related error occurs	 */	public static void processInteractive(		boolean hasFile,		boolean doEcho,		boolean scolonterm,		String user	)		throws IOException, SQLException	{		// an SQL stack keeps track of ( " and '		SQLStack stack = new SQLStack();		// a query part is a line of an SQL query		QueryPart qp = null;		String query = "", curLine;		StringBuffer rl = new StringBuffer();		boolean wasComplete = true, doProcess, lastac = false;		if (!hasFile) {			lastac = con.getAutoCommit();			out.println("auto commit mode: " + (lastac ? "on" : "off"));			out.print(getPrompt(user, stack, true));			out.flush();		}		// the main (interactive) process loop		int i = 0;		char c = 0;		for (i = 1; true; i++) {			// Manually read a line, because we want to detect an EOF			// (ctrl-D).  Doing so allows to have a terminator for query			// which is not based on a special character, as is the			// problem for XQuery			curLine = in.readLine();			if (curLine == null) {				out.println("");				if (query != "") {					try {						executeQuery(query, stmt, out);					} catch (SQLException e) {						out.flush();						if (hasFile) {							System.err.println("Error on line " + i + ": " + e.getMessage());						} else {							System.err.println("Error: " + e.getMessage());						}						// print all error messages in the chain (if any)						while ((e = e.getNextException()) != null) {							System.err.println(e.getMessage());						}					}					query = "";					wasComplete = true;					if (!hasFile) {						boolean ac = con.getAutoCommit();						if (ac != lastac) {							out.println("auto commit mode: " + (ac ? "on" : "off"));							lastac = ac;						}						out.print(getPrompt(user, stack, wasComplete));					}					out.flush();					// try to read again					continue;				} else {					// user did ctrl-D without something in the buffer,					// so terminate					break;				}			}			if (doEcho) {				out.println(curLine);				out.flush();			}			qp = scanQuery(curLine, stack, scolonterm);			if (!qp.isEmpty()) {				doProcess = true;				if (wasComplete) {					doProcess = false;					// check for commands only when the previous row was					// complete					if (qp.getQuery().equals("\\q")) {						// quit						break;					} else if (qp.getQuery().startsWith("\\h")) {						out.println("Available commands:");						out.println("\\q      quits this program");						out.println("\\h      this help screen");						if (dbmd != null)							out.println("\\d      list available tables and views");						out.println("\\d<obj> describes the given table or view");						out.println("\\l<uri> executes the contents of the given file or URL");						out.println("\\i<uri> batch executes the inserts from the given file or URL");					} else if (dbmd != null && qp.getQuery().startsWith("\\d")) {						try {							String object = qp.getQuery().substring(2).trim().toLowerCase();							if (scolonterm && object.endsWith(";"))								object = object.substring(0, object.length() - 1);							if (!object.equals("")) {								int dot;								String schema;								if ((dot = object.indexOf(".")) != -1) {									// use provided schema									schema = object.substring(0, dot);									object = object.substring(dot + 1);								} else {									// get current schema									ResultSet rs = stmt.executeQuery("SELECT current_schema");									if (!rs.next())										throw new SQLException("current schema unknown!");									schema = rs.getString(1);									rs.close();								}								ResultSet tbl = dbmd.getTables(										null, schema, null, null);								// we have an object, see if we can find it								boolean found = false;								while (tbl.next()) {									if (tbl.getString("TABLE_NAME").equalsIgnoreCase(object) ||											(tbl.getString("TABLE_SCHEM") + "." + tbl.getString("TABLE_NAME")).equalsIgnoreCase(object)) {										// we found it, describe it										e.dumpSchema(												dbmd,												tbl.getString("TABLE_TYPE"),												tbl.getString("TABLE_CAT"),												tbl.getString("TABLE_SCHEM"),												tbl.getString("TABLE_NAME")												);										found = true;										break;											}								}								if (!found) System.err.println("Unknown table or view: " + object);								tbl.close();							} else {								String[] types = {"TABLE", "VIEW"};								// get current schema								ResultSet rs = stmt.executeQuery("SELECT current_schema");								if (!rs.next())									throw new SQLException("current schema unknown!");								ResultSet tbl = dbmd.getTables(										null, rs.getString(1), null, types);								rs.close();								// give us a list with tables								while (tbl.next()) {									out.println(tbl.getString("TABLE_TYPE") + "\t" +											tbl.getString("TABLE_SCHEM") + "." +											tbl.getString("TABLE_NAME"));								}								tbl.close();							}						} catch (SQLException e) {							out.flush();							System.err.println("Error: " + e.getMessage());						}					} else if (qp.getQuery().startsWith("\\l") ||							qp.getQuery().startsWith("\\i"))					{						String object = qp.getQuery().substring(2).trim();						if (scolonterm && object.endsWith(";"))							object = object.substring(0, object.length() - 1);						if (object.equals("")) {							System.err.println("Usage: '" + qp.getQuery().substring(0, 2) + "<uri>' where <uri> is a file or URL");						} else {							// temporarily redirect input from in							BufferedReader console = in;							try {								in = getReader(object);								if (qp.getQuery().startsWith("\\l")) {									processInteractive(										true, doEcho, scolonterm, user);								} else {									processBatch(0);								}							} catch (Exception e) {								out.flush();								System.err.println("Error: " + e.getMessage());							} finally {								// put back in redirection								in = console;							}						}					} else {						doProcess = true;					}				}				if (doProcess) {					query += qp.getQuery() + (qp.hasOpenQuote() ? "\\n" : " ");					if (qp.isComplete()) {						// strip off trailing ';'						query = query.substring(0, query.length() - 2);						// execute query						try {							executeQuery(query, stmt, out);						} catch (SQLException e) {							out.flush();							if (hasFile) {								System.err.println("Error on line " + i + ": " + e.getMessage());							} else {								System.err.println("Error: " + e.getMessage());							}						}						query = "";						wasComplete = true;					} else {						wasComplete = false;					}				}			}			if (!hasFile) {				boolean ac = con.getAutoCommit();				if (ac != lastac) {					out.println("auto commit mode: " + (ac ? "on" : "off"));					lastac = ac;				}				out.print(getPrompt(user, stack, wasComplete));			}			out.flush();		}	}	/**	 * Executes the given query and prints the result tabularised to the	 * given PrintWriter stream.  The result of this method is the	 * default output of a query: tabular data.	 *	 * @param query the query to execute	 * @param stmt the Statement to execute the query on	 * @param out the PrintWriter to write to	 * @throws SQLException if a database related error occurs	 */	private static void executeQuery(String query,			Statement stmt,			PrintWriter out)		throws SQLException	{		// warnings generated during querying		SQLWarning warn;		// execute the query, let the driver decide what type it is		int aff = -1;		boolean	nextRslt = stmt.execute(query);		if (!nextRslt) aff = stmt.getUpdateCount();		do {			if (nextRslt) {				// we have a ResultSet, print it				ResultSet rs = stmt.getResultSet();				e.dumpResultSet(rs);				// if there were warnings for this result,				// show them!				warn = rs.getWarnings();				if (warn != null) {					// force stdout to be written so the					// warning appears below it					out.flush();					do {						System.err.println("ResultSet warning: " +							warn.getMessage());						warn = warn.getNextWarning();					} while (warn != null);					rs.clearWarnings();				}				rs.close();			} else if (aff != -1) {				if (aff == Statement.SUCCESS_NO_INFO) {					out.println("Operation successful");				} else {					// we have an update count					out.println(aff + " affected row" + (aff != 1 ? "s" : ""));

⌨️ 快捷键说明

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