postgresmodule.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,483 行 · 第 1/5 页
JAVA
2,483 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */package com.caucho.quercus.lib.db;import com.caucho.quercus.UnimplementedException;import com.caucho.quercus.annotation.NotNull;import com.caucho.quercus.annotation.Optional;import com.caucho.quercus.annotation.ReturnNullAsFalse;import com.caucho.quercus.env.*;import com.caucho.quercus.module.AbstractQuercusModule;import com.caucho.util.CharBuffer;import com.caucho.util.L10N;import com.caucho.util.Log;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.vfs.WriteStream;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLWarning;import java.sql.Statement;import java.sql.Types;import java.util.HashMap;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;// Do not add new compile dependencies (use reflection instead)// import org.postgresql.largeobject.*;/** * Quercus postgres routines. */public class PostgresModule extends AbstractQuercusModule { private static final Logger log = Log.open(PostgresModule.class); private static final L10N L = new L10N(PostgresModule.class); public static final int PGSQL_ASSOC = 0x01; public static final int PGSQL_NUM = 0x02; public static final int PGSQL_BOTH = 0x03; public static final int PGSQL_CONNECT_FORCE_NEW = 0x04; public static final int PGSQL_CONNECTION_BAD = 0x05; public static final int PGSQL_CONNECTION_OK = 0x06; public static final int PGSQL_SEEK_SET = 0x07; public static final int PGSQL_SEEK_CUR = 0x08; public static final int PGSQL_SEEK_END = 0x09; public static final int PGSQL_EMPTY_QUERY = 0x0A; public static final int PGSQL_COMMAND_OK = 0x0B; public static final int PGSQL_TUPLES_OK = 0x0C; public static final int PGSQL_COPY_OUT = 0x0D; public static final int PGSQL_COPY_IN = 0x0E; public static final int PGSQL_BAD_RESPONSE = 0x0F; public static final int PGSQL_NONFATAL_ERROR = 0x10; public static final int PGSQL_FATAL_ERROR = 0x11; public static final int PGSQL_TRANSACTION_IDLE = 0x12; public static final int PGSQL_TRANSACTION_ACTIVE = 0x13; public static final int PGSQL_TRANSACTION_INTRANS = 0x14; public static final int PGSQL_TRANSACTION_INERROR = 0x15; public static final int PGSQL_TRANSACTION_UNKNOWN = 0x16; public static final int PGSQL_DIAG_SEVERITY = 0x17; public static final int PGSQL_DIAG_SQLSTATE = 0x18; public static final int PGSQL_DIAG_MESSAGE_PRIMARY = 0x19; public static final int PGSQL_DIAG_MESSAGE_DETAIL = 0x20; public static final int PGSQL_DIAG_MESSAGE_HINT = 0x21; public static final int PGSQL_DIAG_STATEMENT_POSITION = 0x22; public static final int PGSQL_DIAG_INTERNAL_POSITION = 0x23; public static final int PGSQL_DIAG_INTERNAL_QUERY = 0x24; public static final int PGSQL_DIAG_CONTEXT = 0x25; public static final int PGSQL_DIAG_SOURCE_FILE = 0x26; public static final int PGSQL_DIAG_SOURCE_LINE = 0x27; public static final int PGSQL_DIAG_SOURCE_FUNCTION = 0x28; public static final int PGSQL_ERRORS_TERSE = 0x29; public static final int PGSQL_ERRORS_DEFAULT = 0x2A; public static final int PGSQL_ERRORS_VERBOSE = 0x2B; public static final int PGSQL_STATUS_LONG = 0x2C; public static final int PGSQL_STATUS_STRING = 0x2D; public static final int PGSQL_CONV_IGNORE_DEFAULT = 0x2E; public static final int PGSQL_CONV_FORCE_NULL = 0x2F; /** * Constructor */ public PostgresModule() { } /** * Returns true for the postgres extension. */ public String []getLoadedExtensions() { return new String[] { "postgres", "pgsql" }; } /** * Returns number of affected records (tuples) */ public static int pg_affected_rows(Env env, @NotNull PostgresResult result) { try { if (result == null) return -1; return result.getAffectedRows(); } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return 0; } } /** * pg_affected_rows() alias. */ public static int pg_cmdtuples(Env env, @NotNull PostgresResult result) { if (result == null) return -1; return pg_affected_rows(env, result); } /** * Cancel an asynchronous query */ public static boolean pg_cancel_query(Env env, @NotNull Postgres conn) { try { if (conn == null) return false; conn.setAsynchronousStatement(null); conn.setAsynchronousResult(null); return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Gets the client encoding */ @ReturnNullAsFalse public static String pg_client_encoding(Env env, @Optional Postgres conn) { try { if (conn == null) conn = getConnection(env); return conn.getClientEncoding(); } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return null; } } /** * Closes a PostgreSQL connection */ public static boolean pg_close(Env env, @Optional Postgres conn) { try { if (conn == null) conn = getConnection(env); if (conn != null) { if (conn == getConnection(env)) env.removeSpecialValue("caucho.postgres"); conn.close(env); return true; } } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); } return false; } /** * Open a PostgreSQL connection */ @ReturnNullAsFalse public static Postgres pg_connect(Env env, String connectionString, @Optional int connectionType) { try { String host = "localhost"; int port = 5432; String dbName = ""; String userName = ""; String password = ""; HashMap<String, String> nameValueMap = parseConnectionString(connectionString); String value = nameValueMap.get("host"); if (value != null) host = nameValueMap.get("host"); value = nameValueMap.get("port"); if (value != null) { port = 0; int len = value.length(); for (int i = 0; i < len; i++) { char ch = value.charAt(i); if ('0' <= ch && ch <= '9') port = port * 10 + value.charAt(i) - '0'; else break; } } value = nameValueMap.get("dbname"); if (value != null) dbName = value; value = nameValueMap.get("user"); if (value != null) userName = value; value = nameValueMap.get("password"); if (value != null) password = value; String driver = "org.postgresql.Driver"; String url = "jdbc:postgresql://" + host + ":" + port + "/" + dbName; Postgres postgres = new Postgres(env, host, userName, password, dbName, port, driver, url); if (! postgres.isConnected()) return null; env.setSpecialValue("caucho.postgres", postgres); return postgres; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return null; } } /** * Returns the name/value pairs from the postgres connection string. */ private static HashMap<String, String> parseConnectionString(String s) { HashMap<String, String> map = new HashMap<String, String>(); char ch; int len = s.length(); int i = 0; CharBuffer buffer = new CharBuffer(); while (i < len) { buffer.clear(); // skip whitespace for (; i < len && Character.isWhitespace(ch = s.charAt(i)); i++) { } // get name for (; i < len && ! Character.isWhitespace(ch = s.charAt(i)) && ch != '=' ; i++) { buffer.append(ch); } String name = buffer.toString(); buffer.clear(); // skip until '=' while (i < len && (ch = s.charAt(i++)) != '=') { } // skip whitespace for (; i < len && Character.isWhitespace(ch = s.charAt(i)); i++) { } boolean isQuoted = false; // value may be quoted if (i < len) { if ((ch = s.charAt(i++)) == '\'') isQuoted = true; else buffer.append(ch); } boolean isEscaped = false; // get value loop: while (i < len) { ch = s.charAt(i++); switch(ch) { case '\\': if (isEscaped) buffer.append(ch); isEscaped = !isEscaped; break; case '\'': if (isEscaped) { buffer.append(ch); isEscaped = false; break; } else if (isQuoted) break loop; case ' ': case '\n': case '\r': case '\f': case '\t': if (isQuoted) { buffer.append(ch); break; } else if (isEscaped) { buffer.append('\\'); break loop; } else break loop; default: if (isEscaped) { buffer.append('\\'); isEscaped = false; } buffer.append(ch); } } String value = buffer.toString(); if (name.length() > 0) map.put(name, value); } return map; } /** * Get connection is busy or not */ public static boolean pg_connection_busy(Env env, @NotNull Postgres conn) { // Always return false, for now (pg_send_xxxx are not asynchronous) // so there should be no reason for a connection to become busy in // between different pg_xxx calls. return false; } /** * Reset connection (reconnect) */ public static boolean pg_connection_reset(Env env, @NotNull Postgres conn) { try { // Query database name before closing connection String dbname = conn.getDbName(); conn.close(env); conn = new Postgres(env, conn.getHost(), conn.getUserName(), conn.getPassword(), dbname, conn.getPort(), conn.getDriver(), conn.getUrl()); env.setSpecialValue("caucho.postgres", conn); return true; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return false; } } /** * Get connection status */ public static int pg_connection_status(Env env, @NotNull Postgres conn) { try { boolean ping = pg_ping(env, conn); return ping ? PGSQL_CONNECTION_OK : PGSQL_CONNECTION_BAD; } catch (Exception ex) { log.log(Level.FINE, ex.toString(), ex); return PGSQL_CONNECTION_BAD; } } /** * Convert associative array values into suitable for SQL statement */ @ReturnNullAsFalse public static ArrayValue pg_convert(Env env, @NotNull Postgres conn, String tableName, ArrayValue assocArray, @Optional("0") int options) { try { // XXX: options has not been implemented yet. // XXX: the following PHP note has not been implemented yet. // Note: If there are boolean fields in table_name don't use // the constant TRUE in assoc_array. It will be converted to the // string 'TRUE' which is no valid entry for boolean fields in // PostgreSQL. Use one of t, true, 1, y, yes instead. if (options > 0) { throw new UnimplementedException("pg_convert with options"); } PostgresResult result; Connection jdbcConn = conn.getJavaConnection(); DatabaseMetaData dbMetaData = jdbcConn.getMetaData(); ResultSet rs = dbMetaData.getColumns("", "", tableName, ""); // Check column count
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?