📄 database.java
字号:
} } /** * <p> Execute the given query. </p> * * @param statement The SQL query statement to exectute * @param keepOpen If true, the resultset must be closed with the free() method * @return the result of the query */ public static ResultSet query(String statement, boolean keepOpen) throws SQLException { // Try to execute. If we get a SocketException, wait and try again //boolean firstTry = true; while (true) { try { Statement st = getStatement(null, !keepOpen); ResultSet rs = st.executeQuery(statement); if (keepOpen) { statementMap.put(rs, st); } return rs; } catch (Exception e) { e.printStackTrace(System.err); if (e instanceof SQLException) { SQLException sqle = (SQLException)e; String msg = sqle.getMessage(); if (msg.indexOf("broken the connection") < 0 && msg.indexOf("SocketException") < 0 && msg.indexOf("Connection is closed") < 0) { System.err.println("SQLException for update statement: " + statement); throw sqle; } } DBDescr db = getDBDescr(null); synchronized (db) { if (db.verifyConnection()) continue; //System.out.println("Verify failed..."); if (db.reconnect()) continue; // That didn't work; log error String msg = e.getMessage(); int idx; if (msg != null && (idx=msg.indexOf("Stack Trace")) >= 0) msg = msg.substring(0, idx-1); Log.e("DATABASE-QUERY", "Got Exception; database is probably down: " + msg); if (db.getReturnOnReconnectFail()) { throw new SQLException("Got Exception; database is probably down: " + msg); } while (!db.verifyConnection()) { try { Thread.sleep(DEFAULT_RECONNECT_WAIT_TIME); //System.out.println("Done sleeping, reconnect.."); db.reconnect(); } catch (InterruptedException ie) { } } } } } } /** * <p> Begin a transaction. The database will not be changed until * either commit() or rollback() is called. </p> */ public static void beginTransaction() throws SQLException { try { getDBDescr(null).beginTransaction(); } catch (SQLException e) { e.printStackTrace(System.err); throw e; } } /** * <p> If a transaction is in progress, commit it, then go back to * autocommit mode. Use beginTransaction() to start a new * transaction. </p> */ public static void commit() throws SQLException { //System.out.println("["+Integer.toHexString(Thread.currentThread().hashCode())+"] "+"Entering commit"); try { getDBDescr(null).commit(); } catch (SQLException e) { e.printStackTrace(System.err); throw e; } } /** * <p> If a transaction is in progress, roll back any changes, then * go back to autocommit mode. Use beginTransaction() to start a new * transaction. </p> */ public static void rollback() throws SQLException { try { getDBDescr(null).rollback(); } catch (SQLException e) { e.printStackTrace(System.err); throw e; } } /** * <p> Insert a row in the database and return the sequence number * used for the row. </p> * * <p> Currently this only works for the PostgreSQL database. This * method assumes that the first two elements of the fieldValues * argument are the name of the id-column which is to be assigned * the sequence number and a dummy value respectably. </p> * * <p> If the given seqName is null, it is assumed to be * "tablename_idfieldname_seq". </p> * * @param table The name of the table in which the row is to be inserted * @param fieldValues The names of columns and the values to be inserted * @param seqName The name of the sequence from which to obtain the sequence number, or null * * @return the sequence number for the row */ public static String insert(String table, String[] fieldValues, String seqName) throws SQLException { if (seqName == null) seqName = table + "_" + fieldValues[0] + "_seq"; Statement stUpdate = getUpdateStatement(null); ResultSet rs = stUpdate.executeQuery("SELECT nextval('" + seqName + "') AS seqnum"); if (!rs.next()) throw new SQLException("Failed to get a sequence number from " + seqName); String seqNum = rs.getString("seqnum"); fieldValues[1] = seqNum; insert(table, fieldValues); return seqNum; } /** * <p> Insert a row in the specified table. </p> * * <p> The fieldValues argument must contain an even number of * elements, and each pair of consecutive elements must specify the * name of the column and the value to be inserted in said column * respectably. </p> * * @param table The name of the table in which the row is to be inserted * @param fieldValues The names of columns and the values to be inserted * * @return the number of inserted rows, which is always 1 */ public static int insert(String table, String[] fieldValues) throws SQLException { if ((fieldValues.length & 0x1) == 1) return -1; String query = "INSERT INTO " + table + " ("; boolean first = true; for (int i = 0; i < fieldValues.length; i += 2) { if (fieldValues[i+1] != null) { if (!first) { query += ","; } else { first = false; } query += addSlashesStrict(fieldValues[i]); } } query += ") VALUES ("; first = true; for (int i = 1; i < fieldValues.length; i += 2) { if (fieldValues[i] != null) { if (!first) { query += ","; } else { first = false; } boolean fnutt = true; if (fieldValues[i].equals("NOW()") || fieldValues[i].equals("null") || (fieldValues[i].startsWith("(") && !fieldValues[i].equals("(null)"))) { fnutt = false; } if (fnutt) { query += "'" + addSlashesStrict(fieldValues[i]) + "'"; } else { query += fieldValues[i]; } } } query += ")"; return update(query); } /** * <p> Update rows in the specified table. </p> * * <p> The fieldValues argument must contain an even number of * elements, and each pair of consecutive elements must specify the * name of the column and the new value to be set in said column * respectably. </p> * * <p> The keyFieldValues specifies which rows to update; it must * contain an even number of elements, and each pair of consecutive * elements must specify the name of the column and the value said * column must have for the row to be included in the update * respectable. </p> * * @param table The name of the table in which the row is to be inserted * @param fieldValues The names of columns and the values to be inserted * * @return the number of updated rows. */ public static int update(String table, String[] fieldValues, String[] keyFieldValues) throws SQLException { if ((fieldValues.length & 0x1) == 1 || (keyFieldValues.length & 0x1) == 1) return -1; String query = "UPDATE " + table + " SET "; boolean noUpdate = true; boolean first = true; for (int i = 0; i < fieldValues.length; i += 2) { if (fieldValues[i+1] != null) { if (!first) { query += ","; } else { first = false; } noUpdate = false; boolean fnutt = true; if (fieldValues[i+1].equals("NOW()") || fieldValues[i+1].equals("null") || (fieldValues[i+1].startsWith("(") && !fieldValues[i+1].equals("(null)"))) { fnutt = false; } if (fnutt) { query += fieldValues[i] + "=" + "'" + addSlashesStrict(fieldValues[i+1]) + "'"; } else { query += fieldValues[i] + "=" + fieldValues[i+1]; } } } if (noUpdate) return 0; query += " WHERE "; for (int i = 0; i < keyFieldValues.length; i += 2) { if (i != 0) query += " AND "; query += keyFieldValues[i] + "='" + addSlashesStrict(keyFieldValues[i+1]) + "'"; } return update(query); } /** * <p> Execute the given statement, and return the number of rows * updated. </p> * * @param statement The statement to execute * @return the number of rows updated */ public static int update(String statement) throws SQLException { while (true) { try { Statement stUpdate = getUpdateStatement(null); return stUpdate.executeUpdate(statement); } catch (Exception e) { e.printStackTrace(System.err); if (e instanceof SQLException) { SQLException sqle = (SQLException)e; String msg = sqle.getMessage(); if (msg.indexOf("broken the connection") < 0 && msg.indexOf("SocketException") < 0 && msg.indexOf("Connection is closed") < 0) { System.err.println("SQLException for update statement: " + statement); throw sqle; } } DBDescr db = getDBDescr(null); synchronized (db) { if (db.verifyConnection()) continue; //System.out.println("Verify failed..."); if (db.reconnect()) continue; // That didn't work; log error String msg = e.getMessage(); int idx; if (msg != null && (idx=msg.indexOf("Stack Trace")) >= 0) msg = msg.substring(0, idx-1); Log.e("DATABASE-UPDATE", "Got Exception; database is probably down: " + msg); if (db.getReturnOnReconnectFail()) { throw new SQLException("Got Exception; database is probably down: " + msg); } while (!db.verifyConnection()) { try { Thread.sleep(DEFAULT_RECONNECT_WAIT_TIME); //System.out.println("Done sleeping, reconnect.."); db.reconnect(); } catch (InterruptedException ie) { } } } } } } /** * <p> Return all columns from the current row in rs in a HashMap * </p> * * @param rs ResultSet to fetch row from * @param md Get column names from this object * @return HashMap with all columns from the current row in rs */ public static HashMap getHashFromResultSet(ResultSet rs, ResultSetMetaData md) throws SQLException { HashMap hm = new HashMap(); for (int i=md.getColumnCount(); i > 0; i--) { String s; if ((s=rs.getString(i)) != null) hm.put(md.getColumnName(i), s); } return hm; } /** * <p> Make the given string "safe" (e.g. do not allow ( at the begining). * \) </p> * * @param s The string to make safe * @return a safe version of the string */ public static String addSlashes(String s) { if (s == null) return null; if (s.startsWith("(")) s = "\\" + s; return addSlashesStrict(s); } /** * <p> Escape any special characters in the given string (e.g. ' and * \) </p> * * @param s The string to escape * @return the string with special characters escaped */ private static String addSlashesStrict(String s) { if (s == null) return null; s = insertBefore(s, "\\", "\\"); s = insertBefore(s, "'", "\\"); return s; } private static String insertBefore(String tekst, String oldS, String newS) { if (tekst.indexOf(oldS) == -1) return tekst; StringBuffer b = new StringBuffer(tekst); int pos = -1 - newS.length(); for (;;) { pos = b.toString().indexOf(oldS, pos + 1 + newS.length()); if (pos == -1) break; b.insert(pos, newS); } return b.toString(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -