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 + -
显示快捷键?