📄 monetconnection.java
字号:
* Connection object is in auto-commit mode * @see #setAutoCommit(boolean) */ public void rollback() throws SQLException { // note: can't use sendIndependentCommand here because we need // to process the auto_commit state the server gives // create a container for the result ResponseList l = new ResponseList( 0, 0, ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY ); // send rollback to the server try { l.processQuery("ROLLBACK"); } finally { l.close(); } } /** * Undoes all changes made after the given Savepoint object was set. * <br /><br /> * This method should be used only when auto-commit has been * disabled. * * @param savepoint the Savepoint object to roll back to * @throws SQLException if a database access error occurs, the * Savepoint object is no longer valid, or this Connection * object is currently in auto-commit mode */ public void rollback(Savepoint savepoint) throws SQLException { if (!(savepoint instanceof MonetSavepoint)) throw new SQLException("This driver can only handle savepoints it created itself"); MonetSavepoint sp = (MonetSavepoint)savepoint; // note: can't use sendIndependentCommand here because we need // to process the auto_commit state the server gives // create a container for the result ResponseList l = new ResponseList( 0, 0, ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY ); // send the appropriate query string to the database try { l.processQuery("ROLLBACK TO SAVEPOINT " + sp.getName()); } finally { l.close(); } } /** * Sets this connection's auto-commit mode to the given state. If a * connection is in auto-commit mode, then all its SQL statements * will be executed and committed as individual transactions. * Otherwise, its SQL statements are grouped into transactions that * are terminated by a call to either the method commit or the * method rollback. By default, new connections are in auto-commit * mode. * <br /><br /> * The commit occurs when the statement completes or the next * execute occurs, whichever comes first. In the case of statements * returning a ResultSet object, the statement completes when the * last row of the ResultSet object has been retrieved or the * ResultSet object has been closed. In advanced cases, a single * statement may return multiple results as well as output parameter * values. In these cases, the commit occurs when all results and * output parameter values have been retrieved. * <br /><br /> * NOTE: If this method is called during a transaction, the * transaction is committed. * * @param autoCommit true to enable auto-commit mode; false to disable it * @throws SQLException if a database access error occurs * @see #getAutoCommit() */ public void setAutoCommit(boolean autoCommit) throws SQLException { if (this.autoCommit != autoCommit) { sendControlCommand("auto_commit " + (autoCommit ? "1" : "0")); this.autoCommit = autoCommit; } } /** * Sets the given catalog name in order to select a subspace of this * Connection object's database in which to work. If the driver * does not support catalogs, it will silently ignore this request. */ public void setCatalog(String catalog) throws SQLException { // silently ignore this request } public void setHoldability(int holdability) {} /** * Puts this connection in read-only mode as a hint to the driver to * enable database optimizations. MonetDB doesn't support writable * ResultSets, hence an SQLException is thrown if attempted to set * to false here. * * @param readOnly true enables read-only mode; false disables it * @throws SQLException if a database access error occurs or this * method is called during a transaction or set to false. */ public void setReadOnly(boolean readOnly) throws SQLException { if (autoCommit == false) throw new SQLException("changing read-only setting not allowed during transactions"); if (readOnly == false) throw new SQLException("writable mode not supported"); } /** * Creates an unnamed savepoint in the current transaction and * returns the new Savepoint object that represents it. * * @return the new Savepoint object * @throws SQLException if a database access error occurs or this Connection * object is currently in auto-commit mode */ public Savepoint setSavepoint() throws SQLException { // create a new Savepoint object MonetSavepoint sp = new MonetSavepoint(); // note: can't use sendIndependentCommand here because we need // to process the auto_commit state the server gives // create a container for the result ResponseList l = new ResponseList( 0, 0, ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY ); // send the appropriate query string to the database try { l.processQuery("SAVEPOINT " + sp.getName()); } finally { l.close(); } return(sp); } /** * Creates a savepoint with the given name in the current * transaction and returns the new Savepoint object that represents * it. * * @param name a String containing the name of the savepoint * @return the new Savepoint object * @throws SQLException if a database access error occurs or this Connection * object is currently in auto-commit mode */ public Savepoint setSavepoint(String name) throws SQLException { // create a new Savepoint object MonetSavepoint sp; try { sp = new MonetSavepoint(name); } catch (IllegalArgumentException e) { throw new SQLException(e.getMessage()); } // note: can't use sendIndependentCommand here because we need // to process the auto_commit state the server gives // create a container for the result ResponseList l = new ResponseList( 0, 0, ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY ); // send the appropriate query string to the database try { l.processQuery("SAVEPOINT " + sp.getName()); } finally { l.close(); } return(sp); } /** * Attempts to change the transaction isolation level for this * Connection object to the one given. The constants defined in the * interface Connection are the possible transaction isolation * levels. * * @param level one of the following Connection constants: * Connection.TRANSACTION_READ_UNCOMMITTED, * Connection.TRANSACTION_READ_COMMITTED, * Connection.TRANSACTION_REPEATABLE_READ, or * Connection.TRANSACTION_SERIALIZABLE. */ public void setTransactionIsolation(int level) { if (level != TRANSACTION_SERIALIZABLE) { addWarning("MonetDB only supports fully serializable " + "transactions, continuing with transaction level " + "raised to TRANSACTION_SERIALIZABLE"); } } /** * Installs the given TypeMap object as the type map for this * Connection object. The type map will be used for the custom * mapping of SQL structured types and distinct types. * * @param map the java.util.Map object to install as the replacement for * this Connection object's default type map */ public void setTypeMap(Map map) { typeMap = map; } /** * Returns a string identifying this Connection to the MonetDB * server. * * @return a String representing this Object */ public String toString() { String language = ""; if (lang == LANG_XQUERY) language = "?language=xquery"; else if (lang == LANG_MIL) language = "?language=mil"; return("MonetDB Connection (jdbc:monetdb://" + hostname + ":" + port + "/" + database + language + ") " + (closed ? "connected" : "disconnected")); } //== end methods of interface Connection /** * Sends the given string to MonetDB as regular statement, making * sure there is a prompt after the command is sent. All possible * returned information is discarded. Encountered errors are * reported. * * @param command the exact string to send to MonetDB * @throws SQLException if an IO exception or a database error occurs */ void sendIndependantCommand(String command) throws SQLException { synchronized (monet) { try { monet.writeLine(queryTempl, command); String error = monet.waitForPrompt(); if (error != null) throw new SQLException(error); } catch (IOException e) { throw new SQLException(e.getMessage()); } } } /** * Sends the given string to MonetDB as control statement, making * sure there is a prompt after the command is sent. All possible * returned information is discarded. Encountered errors are * reported. * * @param command the exact string to send to MonetDB * @throws SQLException if an IO exception or a database error occurs */ void sendControlCommand(String command) throws SQLException { // send X command synchronized (monet) { try { monet.writeLine(commandTempl, command); String error = monet.waitForPrompt(); if (error != null) throw new SQLException(error); } catch (IOException e) { throw new SQLException(e.getMessage()); } } } /** * Sends the given string to MonetDB as data; it is sent using a * special Xcopy mode of the server, allowing not to make any * changes to the given in String. A Response is returned, just * like for a normal query. * * @param in the exact string to send to MonetDB * @param name the name to associate to the data in in * @return A Response object, or null if no response * @throws SQLException if a database error occurs */ Response copyToServer(String in, String name) throws SQLException { synchronized (monet) { // TODO: maybe in the future add support for a second // name which is a convenience "alias" (e.g. in XQuery) // tell server we're going to "copy" data over to be // stored under the given name, make up something if the // caller doesn't know it too if (name == null) { name = "doc_" + System.currentTimeMillis() + ".xml"; addWarning("adding new document with name: " + name); } sendControlCommand("copy " + name); // the server is waiting for data to come String[] templ = new String[3]; // empty on everything ResponseList l = new ResponseList( 0, 0, ResultSet.FETCH_FORWARD, ResultSet.CONCUR_READ_ONLY ); try { l.executeQuery(templ, in); return(l.getNextResponse()); // don't you love Java? } finally { l.close(); } } } /** * Adds a warning to the pile of warnings this Connection object * has. If there were no warnings (or clearWarnings was called) * this warning will be the first, otherwise this warning will get * appended to the current warning. * * @param reason the warning message */ void addWarning(String reason) { if (warnings == null) { warnings = new SQLWarning(reason); } else { warnings.setNextWarning(new SQLWarning(reason)); } } /** the default number of rows that are (attempted to) read at once */ private final static int DEF_FETCHSIZE = 250; /** The sequence counter */ private static int seqCounter = 0; /** An optional thread that is used for sending large queries */ private SendThread sendThread = null; /** * Returns the numeric value in the given CharBuffer. The value is * considered to end at the end of the CharBuffer or at a space. If * a non-numeric character is encountered a ParseException is * thrown. * * @param str CharBuffer to read from * @throws java.text.ParseException if no numeric value could be * read */ private final int parseNumber(CharBuffer str) throws java.text.ParseException { if (!str.hasRemaining()) throw new java.text.ParseException("Unexpected end of string", str.position() - 1); int tmp = MonetResultSet.getIntrinsicValue(str.get(), str.position() - 1); char chr; while (str.hasRemaining() && (chr = str.get()) != ' ') { tmp *= 10; tmp += MonetResultSet.getIntrinsicValue(chr, str.position() - 1); } return(tmp); } /** * A Response is a message sent by the server to indicate some * action has taken place, and possible results of that action. */ // {{{ interface Response interface Response { /** * Adds a line to the underlying Response implementation. * * @param line the header line as String * @param linetype the line type according to the MAPI protocol * @return a non-null String if the line is invalid, * or additional lines are not allowed. */ public abstract String addLine(String line, int linetype); /** * Returns whether this Reponse expects more lines to be added * to it. * * @return true if a next line should be added, false otherwise */ public abstract boolean wantsMore(); /** * Indicates that no more header lines will be added to this * Response implementation. * * @throws SQLException if the contents of the Response is not * consistent or sufficient. */ public abstract void complete() throws SQLException; /** * Instructs the Response implementation to close and do the * necessary clean up procedures. * * @throws SQLException */ public abstract void close(); } // }}} /** * The ResultSetResponse represents a tabular result sent by the * server. This is typically an SQL table. The MAPI headers of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -