All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.caucho.quercus.lib.db.MysqlModule Maven / Gradle / Ivy

There is a newer version: 4.0.66
Show newest version
/*
 * Copyright (c) 1998-2012 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 Scott Ferguson
 */

package com.caucho.quercus.lib.db;

import com.caucho.quercus.annotation.NotNull;
import com.caucho.quercus.annotation.Optional;
import com.caucho.quercus.env.BooleanValue;
import com.caucho.quercus.env.ConstStringValue;
import com.caucho.quercus.env.Env;
import com.caucho.quercus.env.LongValue;
import com.caucho.quercus.env.NullValue;
import com.caucho.quercus.env.ObjectValue;
import com.caucho.quercus.env.StringValue;
import com.caucho.quercus.env.Value;
import com.caucho.quercus.module.AbstractQuercusModule;
import com.caucho.util.L10N;
import com.caucho.util.Log;

import java.sql.Connection;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * PHP mysql routines.
 */
public class MysqlModule extends AbstractQuercusModule {

  private static final Logger log = Log.open(MysqlModule.class);
  private static final L10N L = new L10N(MysqlModule.class);

  public static final int MYSQL_ASSOC = JdbcResultResource.FETCH_ASSOC;
  public static final int MYSQL_NUM = JdbcResultResource.FETCH_NUM;
  public static final int MYSQL_BOTH = JdbcResultResource.FETCH_BOTH;

  public static final int MYSQL_USE_RESULT = 0x0;
  public static final int MYSQL_STORE_RESULT = 0x1;

  private static final StringValue SV_NAME
    = new ConstStringValue("name");
  private static final StringValue SV_TABLE
    = new ConstStringValue("table");
  private static final StringValue SV_DEF
    = new ConstStringValue("def");
  private static final StringValue SV_MAX_LENGTH
    = new ConstStringValue("max_length");
  private static final StringValue SV_NOT_NULL
    = new ConstStringValue("not_null");
  private static final StringValue SV_PRIMARY_KEY
    = new ConstStringValue("primary_key");
  private static final StringValue SV_MULTIPLE_KEY
    = new ConstStringValue("multiple_key");
  private static final StringValue SV_UNIQUE_KEY
    = new ConstStringValue("unique_key");
  private static final StringValue SV_NUMERIC
    = new ConstStringValue("numeric");
  private static final StringValue SV_BLOB
    = new ConstStringValue("blob");
  private static final StringValue SV_TYPE
    = new ConstStringValue("type");
  private static final StringValue SV_UNSIGNED
    = new ConstStringValue("unsigned");
  private static final StringValue SV_ZEROFILL
    = new ConstStringValue("zerofill");

  public MysqlModule()
  {
  }

  /**
   * Returns true for the mysql extension.
   */
  public String []getLoadedExtensions()
  {
    return new String[] { "mysql" };
  }

  /**
   * Returns the number of affected rows.
   */
  public static int mysql_affected_rows(Env env, @Optional Mysqli conn)
  {
    if (conn == null)
      conn = getConnection(env);

    return conn.affected_rows(env);
  }

  /**
   * Get information about the most recent query.
   */
  public static Value mysql_info(Env env, @Optional Mysqli conn)
  {
    if (conn == null)
      conn = getConnection(env);

    return conn.info(env);
  }

  /**
   * Change the logged in user of the current active connection.
   * This function is deprecated and was removed from PHP in PHP 3.0.14.
   */

  public static boolean mysql_change_user(Env env,
                                          StringValue user,
                                          StringValue pass,
                                          @Optional StringValue database,
                                          @Optional Mysqli conn)
  {
    return false;
  }

  /**
   * Returns the client encoding
   */
  public static StringValue mysql_client_encoding(
      Env env, @Optional Mysqli conn)
  {
    if (conn == null)
      conn = getConnection(env);

    return conn.client_encoding(env);
  }

  /**
   * Closes a mysql connection.
   */
  public static boolean mysql_close(Env env, @Optional Mysqli conn)
  {
    boolean isEnvConn = false;

    if (conn == null) {
      conn = (Mysqli) env.getSpecialValue("caucho.mysql");

      isEnvConn = true;
    }

    if (conn == null) {
      // php/1435

      env.warning(L.l("no MySQL-Link resource supplied"));
      return false;
    }

    if (isEnvConn || env.getSpecialValue("caucho.mysql") != null)
      env.removeSpecialValue("caucho.mysql");

    if (conn.isConnected()) {
      conn.close();

      return true;
    }
    else {
      env.warning(
          L.l("connection is either not connected or is already closed"));

      return false;
    }
  }

  /**
   * Creates a database.
   */
  public static boolean mysql_create_db(Env env,
                                        @NotNull StringValue name,
                                        @Optional Mysqli conn)
  {
    if (name.length() == 0)
      return false;

    if (conn == null)
      conn = getConnection(env);

    Statement stmt = null;

    // XXX: move implementation
    try {
      try {
        Connection sqlConn = conn.validateConnection(env).getConnection(env);

        if (sqlConn == null)
          return false;

        stmt = sqlConn.createStatement();
        stmt.setEscapeProcessing(false);
        stmt.executeUpdate("CREATE DATABASE " + name.toString());
      } finally {
        if (stmt != null)
          stmt.close();
      }
    } catch (SQLException e) {
      log.log(Level.FINE, e.toString(), e);
      return false;
    }

    return true;
  }

  /**
   * Moves the intenal row pointer of the MySQL result to the
   * specified row number, 0 based.
   */
  public static boolean mysql_data_seek(Env env,
                                        @NotNull MysqliResult result,
                                        int rowNumber)
  {
    if (result == null)
      return false;

    if (result.seek(env, rowNumber)) {
      return true;
    } else {
      env.warning(
          L.l("Offset {0} is invalid for MySQL "
              + "(or the query data is unbuffered)",
                      rowNumber));
      return false;
    }
  }

  /**
   * Retrieves the database name after a call to mysql_list_dbs()
   */
  public static Value mysql_db_name(Env env,
                                    @NotNull MysqliResult result,
                                    int row,
                                    @Optional("0") Value field)
  {
    if (result == null)
      return BooleanValue.FALSE;

    return mysql_result(env, result, row, field);
  }

  /**
   * Deprecated alias for mysql_db_name
   */
  public static Value mysql_dbname(Env env,
                                   @NotNull MysqliResult result,
                                   int row)
  {
    return mysql_db_name(env, result, row,
                         env.createString("0"));
  }

  /**
   * Returns the value of one field in the result set. FALSE on failure.
   */
  public static Value mysql_result(Env env,
                                   @NotNull MysqliResult result,
                                   int row,
                                   @Optional("0") Value field)
  {
    if (result == null)
      return BooleanValue.FALSE;

    return result.getResultField(env, row, field);
  }

  /**
   * Drops a database.
   */
  public static boolean mysql_drop_db(Env env,
                                      @NotNull StringValue databaseName,
                                      @Optional Mysqli conn)
  {
    if (databaseName.length() == 0)
      return false;

    StringValue query = env.createString("DROP DATABASE " + databaseName);
    Value value = mysql_query(env, query, conn);

    return (value != null && value.toBoolean());
  }

  /**
   * Deprecated alias for mysql_drop_db.
   */
  public static boolean mysql_dropdb(Env env,
                                     @NotNull StringValue databaseName,
                                     @Optional Mysqli conn)
  {
    return mysql_drop_db(env, databaseName, conn);
  }

  /**
   * Returns the error number of the most recent error
   */
  public static int mysql_errno(Env env, @Optional Mysqli conn)
  {
    if (conn == null)
      conn = getConnection(env);

    StringValue error = conn.error(env);

    int errno = conn.errno();

    if (errno != 0)
      return errno;
    else if (error.length() != 0)
      return 2006; // mysql has gone away
    else
      return 0;
  }

  /**
   * Returns the most recent error.
   */
  public static StringValue mysql_error(Env env, @Optional Mysqli conn)
  {
    if (conn == null)
      conn = getConnection(env);

    return conn.error(env);
  }

  /**
   * Deprecated, mysql_real_escape_string() should be used instead.
   *
   * @see StringValue MysqlModule.mysql_real_escape_string(String, Mysqli)
   *
   * @return the escaped string
   */

  public static StringValue mysql_escape_string(Env env, Value val)
  {
    StringValue unescapedString = val.toStringValue();

    StringValue sb = unescapedString.createStringBuilder();

    int len = unescapedString.length();

    for (int i = 0; i < len; i++) {
      char ch = unescapedString.charAt(i);

      switch(ch) {
        case 0:
          sb.append('\\');
          sb.append(0);
          break;
        case '\n':
          sb.append('\\');
          sb.append('n');
          break;
        case '\r':
          sb.append('\\');
          sb.append('r');
          break;
        case '\\':
          sb.append('\\');
          sb.append('\\');
          break;
        case '\'':
          sb.append('\\');
          sb.append('\'');
          break;
        case '"':
          sb.append('\\');
          sb.append('"');
          break;
        case 0x1A:
          sb.append('\\');
          sb.append('Z');
          break;
        default:
          sb.append(ch);
      }
    }

    return sb;
  }

  /**
   * Escapes special characters.
   *
   * @see StringValue MysqliModule.mysqli_real_escape_string(
   * JdbcConnectionResource, String)
   *
   * @return the escaped string
   */

  public static StringValue mysql_real_escape_string(Env env,
                                                     Value val,
                                                     @Optional Mysqli conn)
  {
    StringValue unescapedString = val.toStringValue();

    if (conn == null)
      conn = getConnection(env);

    return conn.real_escape_string(env, unescapedString);
  }

  /**
   * Returns a row from the connection
   */
  public static Value mysql_fetch_array(Env env,
                                        @NotNull MysqliResult result,
                                        @Optional("MYSQL_BOTH") int type)
  {
    if (result == null) {
      return BooleanValue.FALSE;
    }

    Value value = result.fetch_array(env, type);

    if (value != null) {
      return value;
    }
    else {
      return BooleanValue.FALSE;
    }
  }

  /**
   * Returns a row from the connection
   */
  public static Value mysql_fetch_assoc(Env env,
                                        @NotNull MysqliResult result)
  {
    if (result == null) {
      return BooleanValue.FALSE;
    }

    return result.fetch_array(env, MYSQL_ASSOC);
  }

  /**
   * Returns an object containing field information.
   * On success, this method increments the field offset
   * (see {@link #mysql_field_seek}).
   *
   * 

ERRATA

*
    *
  • quercus returns "int" for BIT type, php returns "unknown" *
  • quercus always returns int(0) for unique_key *
  • quercus always returns int(0) for zerofill *
  • quercus always returns int(0) for multiple_key *
* */ public static Value mysql_fetch_field(Env env, @NotNull MysqliResult result, @Optional("-1") int fieldOffset) { /** * ERRATA is also documented in php/142s.qa * There is probably a mysql specific query or API that would be better * for getting this information */ if (result == null) return BooleanValue.FALSE; // php/142v.qa - call must succeed even if some info not available try { if (fieldOffset == -1) { fieldOffset = result.field_tell(env); result.setFieldOffset(fieldOffset + 1); } ResultSetMetaData md = result.getMetaData(); if (md.getColumnCount() <= fieldOffset || fieldOffset < 0) { return BooleanValue.FALSE; } QuercusResultSetMetaData qMd = null; if (md instanceof QuercusResultSetMetaData) qMd = (QuercusResultSetMetaData) md; int jdbcField = fieldOffset + 1; int jdbcColumnType = md.getColumnType(jdbcField); String catalogName = md.getCatalogName(jdbcField); String tableName = md.getTableName(jdbcField); String schemaName = md.getSchemaName(jdbcField); String columnName = md.getColumnName(jdbcField); String columnLabel = md.getColumnLabel(jdbcField); if (schemaName == null || "".equals(schemaName)) schemaName = tableName; if ((tableName == null || "".equals(tableName)) && result.isLastSqlDescribe()) tableName = "COLUMNS"; // some information is not available from the ResultSetMetaData JdbcColumnMetaData columnMd = null; if (qMd == null) { JdbcConnectionResource conn = getConnection(env).validateConnection(env); // php/141p JdbcTableMetaData tableMd = conn.getTableMetaData(env, catalogName, null, tableName); if (tableMd != null) columnMd = tableMd.getColumn(columnName); } // XXX: maxlen note from PHP comments: // the length of the longest value for that field in the returned dataset, // NOT the maximum length of data that column is designed to hold. int maxLength = 0; int notNull = md .isNullable(jdbcField) == ResultSetMetaData.columnNullable ? 0 : 1; int numeric = JdbcColumnMetaData.isNumeric(jdbcColumnType) ? 1 : 0; int blob = JdbcColumnMetaData.isBlob(jdbcColumnType) ? 1 : 0; String type = result.getFieldType(fieldOffset, jdbcColumnType); int unsigned = md.isSigned(jdbcField) ? 0 : numeric; if (jdbcColumnType == Types.BOOLEAN || jdbcColumnType == Types.BIT) unsigned = 0; else if (jdbcColumnType == Types.DECIMAL) numeric = 1; int zerofill = 0; int primaryKey = 0; int multipleKey = 0; int uniqueKey = 0; if (qMd != null) { zerofill = qMd.isZeroFill(jdbcField) ? 1 : 0; primaryKey = qMd.isPrimaryKey(jdbcField) ? 1 : 0; multipleKey = qMd.isMultipleKey(jdbcField) ? 1 : 0; uniqueKey = qMd.isUniqueKey(jdbcField) ? 1 : 0; notNull = qMd.isNotNull(jdbcField) ? 1 : 0; // maxLength = qMd.getLength(jdbcField); } else if (columnMd != null) { zerofill = columnMd.isZeroFill() ? 1 : 0; primaryKey = columnMd.isPrimaryKey() ? 1 : 0; // XXX: not sure what multipleKey is supposed to be // multipleKey = columnMd.isIndex() && !columnMd.isPrimaryKey() ? 1 : 0; uniqueKey = columnMd.isUnique() ? 1 : 0; } else notNull = 1; ObjectValue fieldResult = env.createObject(); fieldResult.putThisField(env, SV_NAME, env.createString(columnLabel)); fieldResult.putThisField(env, SV_TABLE, env.createString(tableName)); fieldResult.putThisField(env, SV_DEF, env.getEmptyString()); fieldResult.putThisField(env, SV_MAX_LENGTH, LongValue.create(maxLength)); fieldResult.putThisField(env, SV_NOT_NULL, LongValue.create(notNull)); fieldResult.putThisField(env, SV_PRIMARY_KEY, LongValue.create(primaryKey)); fieldResult.putThisField(env, SV_MULTIPLE_KEY, LongValue.create(multipleKey)); fieldResult.putThisField(env, SV_UNIQUE_KEY, LongValue.create(uniqueKey)); fieldResult.putThisField(env, SV_NUMERIC, LongValue.create(numeric)); fieldResult.putThisField(env, SV_BLOB, LongValue.create(blob)); fieldResult.putThisField(env, SV_TYPE, env.createString(type)); fieldResult.putThisField(env, SV_UNSIGNED, LongValue.create(unsigned)); fieldResult.putThisField(env, SV_ZEROFILL, LongValue.create(zerofill)); return fieldResult; } catch (SQLException e) { log.log(Level.FINE, e.toString(), e); return BooleanValue.FALSE; } } /** * Executes a query and returns a result set. * * Returns true on update success, false on failure, and a result set * for a successful select */ public static Value mysql_query(Env env, StringValue sql, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.query(env, sql, MYSQL_STORE_RESULT); } /** * Returns an array of lengths. */ public static Value mysql_fetch_lengths(Env env, @NotNull MysqliResult result) { if (result == null) { return BooleanValue.FALSE; } return result.fetch_lengths(); } /** * Returns an object with properties that correspond to the fetched row * and moves the data pointer ahead. */ public static Value mysql_fetch_object(Env env, @NotNull MysqliResult result, @Optional String className, @Optional Value[] args) { if (result == null) { return BooleanValue.FALSE; } Value value = result.fetch_object(env, className, args); // php/142t // must return FALSE for mediawiki if (value.isNull()) value = BooleanValue.FALSE; return value; } /** * Returns a numerical row from the result, FALSE if no more rows. */ public static Value mysql_fetch_row(Env env, @NotNull MysqliResult result) { if (result == null) { return BooleanValue.FALSE; } return result.fetch_row(env); } /** * Returns the field flags of the specified field. The flags * are reported as a space separated list of words, the returned * value can be split using explode(). * * The following flages are reported, older version of MySQL * may not report all flags: *
    *
  • not_null *
  • primary_key *
  • multiple_key *
  • blob *
  • unsigned *
  • zerofill *
  • binary *
  • enum *
  • auto_increment *
  • timestamp *
*/ public static Value mysql_field_flags(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return BooleanValue.FALSE; Value fieldName = result.getFieldName(env, fieldOffset); if (fieldName == BooleanValue.FALSE) return BooleanValue.FALSE; Value fieldTable = result.getFieldTable(env, fieldOffset); Value fieldJdbcType = result.getJdbcType(fieldOffset); String fieldMysqlType = result.getMysqlType(fieldOffset); if ((fieldTable == BooleanValue.FALSE) || (fieldJdbcType == BooleanValue.FALSE) || (fieldMysqlType == null)) return BooleanValue.FALSE; String sql = "SHOW FULL COLUMNS FROM " + fieldTable.toString() + " LIKE \'" + fieldName.toString() + "\'"; Mysqli conn = getConnection(env); Value resultV = conn.validateConnection(env).realQuery(env, sql); Object metaResult = resultV.toJavaObject(); if (metaResult instanceof MysqliResult) return ((MysqliResult) metaResult).getFieldFlagsImproved( env, fieldJdbcType.toInt(), fieldMysqlType); return BooleanValue.FALSE; } /** * Returns field name at given offset. */ public static Value mysql_field_name(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return BooleanValue.FALSE; // XXX : This method can't detect when mysql_field_name() // is invoked with just 2 arguments instead of 3. The // value 0 is passed for fieldOffsetValue when only // two arguments are found. It is not possible to change // to a Value argument since a NullValue is passed for // both the missing argument and NULL literal argument // cases. Also, Vlaue.isset() can't be used since it // returns false for the default NULL and the literal. return result.getFieldName(env, fieldOffset); } /** * Deprecated alias for mysql_field_name. */ public static Value mysql_fieldname(Env env, @NotNull MysqliResult result, int fieldOffset) { return mysql_field_name(env, result, fieldOffset); } /** * Seeks to the specified field offset, the field offset is * is used as the default for the next call to {@link #mysql_fetch_field}. */ public static boolean mysql_field_seek(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return false; return result.field_seek(env, fieldOffset); } /** * Returns the table corresponding to the field. */ public static Value mysql_field_table(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return BooleanValue.FALSE; return result.getFieldTable(env, fieldOffset); } /** * Deprecated alias for mysql_field_table. */ public static Value mysql_fieldtable(Env env, @NotNull MysqliResult result, int fieldOffset) { return mysql_field_table(env, result, fieldOffset); } /** * Returns the field type. */ public static Value mysql_field_type(Env env, @NotNull MysqliResult result, Value fieldOffset) { if (result == null) { return NullValue.NULL; } if (! fieldOffset.isset()) return NullValue.NULL; return result.getFieldType(env, fieldOffset.toInt()); } /** * Deprecated alias for mysql_field_type. */ public static Value mysql_fieldtype(Env env, @NotNull MysqliResult result, Value fieldOffset) { return mysql_field_type(env, result, fieldOffset); } /** * Returns the length of the specified field */ public static Value mysql_field_len(Env env, @NotNull MysqliResult result, @Optional("0") int fieldOffset) { // gallery2 calls this function with 1 arg, so fieldOffset is optional if (result == null) return BooleanValue.FALSE; // ERRATUM: Returns 10 for datatypes DEC and NUMERIC instead of 11 return result.getFieldLength(env, fieldOffset); } /** * Frees a mysql result. */ public static boolean mysql_free_result(@NotNull MysqliResult result) { if (result == null) return false; result.close(); return true; } /** * Alias for mysql_free_result. */ public static boolean mysql_freeresult(@NotNull MysqliResult result) { return mysql_free_result(result); } /** * Returns the MySQL client version. */ public static String mysql_get_client_info(Env env) { return Mysqli.getClientInfoStatic(env); } /** * Returns a string describing the host. */ public static StringValue mysql_get_host_info(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.get_host_info(env); } /** * Returns an integer respresenting the MySQL protocol * version. */ public static int mysql_get_proto_info(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.get_proto_info(); } /** * Returns the MySQL server version. */ public static Value mysql_get_server_info(Env env, @Optional Mysqli conn) { if (conn == null) { conn = getConnection(env); } if (conn != null && conn.isConnected()) return conn.get_server_info(env); else return NullValue.NULL; } /** * returns ID generated for an AUTO_INCREMENT column by the previous * INSERT query on success, 0 if the previous query does not generate * an AUTO_INCREMENT value, or FALSE if no MySQL connection was established */ public static Value mysql_insert_id(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.insert_id(env); } /** * Returns a result pointer containing the * databases available from the current mysql daemon. */ public static Value mysql_list_dbs(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); // php/1451 // need to return results having column name 'Database' for typo3 // // MySQL Connector/J 5.x returns 'SCHEME_NAME' as the column name // for "SHOW DATABASES", while 3.x returns 'Database' return mysql_query(env, env.createString( "SELECT SCHEMA_NAME AS 'Database' " + "FROM information_schema.SCHEMATA"), conn); } /** * Retrieves information about the given table name. * A Result on success, FALSE on failure. */ public static Value mysql_list_fields(Env env, String database, StringValue tableName, @Optional Mysqli conn) { // php/141c // php gives warnings when the table doesn't exist or is an // empty string/null, but not when the database doesn't exist if (database == null || database.length() == 0) return BooleanValue.FALSE; if (tableName.length() == 0) { env.warning(L.l("Tablename cannot be empty")); return BooleanValue.FALSE; } if (conn == null) conn = getConnection(env); if (! conn.select_db(env, database)) return BooleanValue.FALSE; Value result = conn.query(env, env.createString( "SELECT * FROM " + tableName + " WHERE NULL"), 1); if (result == BooleanValue.FALSE) env.warning(L.l("Table '{0}' does not exist", tableName)); return result; } /** * Deprecated alias for mysql_list_fields */ public static Value mysql_listfields(Env env, String databaseName, StringValue tableName, @Optional Mysqli conn) { return mysql_list_fields(env, databaseName, tableName, conn); } /** * Returns result set or false on error */ public static Value mysql_db_query(Env env, String databaseName, StringValue query, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); if (! conn.select_db(env, databaseName)) return BooleanValue.FALSE; return conn.query(env, query, 1); } /** * Selects the database */ public static boolean mysql_select_db(Env env, String dbName, @Optional Mysqli conn) { if (dbName == null || dbName.length() == 0) return false; if (conn == null) conn = getConnection(env, dbName); return conn.select_db(env, dbName); } /** * Retrieves a list of table names from a MySQL database. */ public static Object mysql_list_tables(Env env, StringValue databaseName, @Optional Mysqli conn) { return mysql_query(env, env.createString("SHOW TABLES FROM " + databaseName), conn); } /** * Get number of fields in result */ public static Value mysql_num_fields(Env env, @NotNull MysqliResult result) { if (result == null) return BooleanValue.FALSE; return LongValue.create(result.num_fields()); } /** * Deprecated alias for mysql_num_fields */ public static Value mysql_numfields(Env env, @NotNull MysqliResult result) { return mysql_num_fields(env, result); } /** * Retrieves the number of rows in a result set. */ public static Value mysql_num_rows(Env env, @NotNull MysqliResult result) { if (result == null) return BooleanValue.FALSE; return LongValue.create(result.num_rows()); } /** * Undocumented alias for {#link #mysql_num_rows}. */ public static Value mysql_numrows(Env env, @NotNull MysqliResult result) { return mysql_num_rows(env, result); } /** * Returns a new persistent mysql connection. JDBC has its own pooling * so don't need to do anything different from regular mysql_connect(). */ public static Value mysql_pconnect(Env env, @Optional StringValue server, @Optional StringValue user, @Optional StringValue password, @Optional boolean newLink, @Optional int flags) { Value value = mysql_connect(env, server, user, password, newLink, flags); Mysqli conn = (Mysqli) env.getSpecialValue("caucho.mysql"); if (conn != null && conn.isConnected()) conn.setPersistent(); return value; } /** * Returns a new mysql connection. */ public static Value mysql_connect(Env env, @Optional StringValue host, @Optional StringValue userName, @Optional StringValue password, @Optional boolean isNewLink, @Optional int flags) { int port = -1; String socketStr = ""; String hostStr; String url = null; if (host.length() == 0) { hostStr = env.getIniString("mysql.default_host"); } else { hostStr = host.toString(); } if (hostStr == null || hostStr.length() == 0) { hostStr = "localhost"; } else if (hostStr.startsWith("jdbc:")) { } else { // host string could contain just a host name, // or it could contain a host name // and a port number, or it could contain // a host name and local socket name, or all 3. // // "localhost" // "localhost:3306" // ":3306" // ":/tmp/mysql.sock" // "localhost:/tmp/mysql.sock" // "localhost:3306:/tmp/mysql.sock" int sepIndex = hostStr.indexOf(':'); if (sepIndex > -1) { String tmp; String portStr; tmp = hostStr; hostStr = tmp.substring(0, sepIndex); if (hostStr.length() == 0) { hostStr = "localhost"; } sepIndex++; tmp = tmp.substring(sepIndex); if ((tmp.length() > 0) && (tmp.charAt(0) != '/')) { sepIndex = tmp.indexOf(':'); if (sepIndex > -1) { portStr = tmp.substring(0, sepIndex); sepIndex++; socketStr = tmp.substring(sepIndex); } else { portStr = tmp; } try { port = Integer.parseInt(portStr); } catch (NumberFormatException ex) { // Use default port in case of invalid port number } } else { socketStr = tmp; } } /* String catalog = (String) env.getQuercus().getSpecial("mysql.catalog"); if (catalog == null) catalog = ""; */ } Mysqli mysqli = new MysqliResource(env, hostStr, userName.toString(), password.toString(), "", port, socketStr, flags, null, url, isNewLink); if (! mysqli.isConnected()) return BooleanValue.FALSE; Value value = env.wrapJava(mysqli); env.setSpecialValue("caucho.mysql", mysqli); return value; } /** * Checks if the connection is still valid. */ public static boolean mysql_ping(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.ping(env); } /** * Returns a string with the status of the connection * or NULL if error. */ public static Value mysql_stat(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); Value result = conn.stat(env); return result == BooleanValue.FALSE ? NullValue.NULL : result; } /** * Retrieves the table name corresponding to a field, using * a result return by {@link #mysql_list_tables}. */ public static Value mysql_tablename(Env env, @NotNull MysqliResult result, int i) { if (result == null) return BooleanValue.FALSE; return result.getResultField(env, i, LongValue.ZERO); } /** * Queries the database. */ public static Object mysql_unbuffered_query(Env env, @NotNull StringValue name, @Optional Mysqli conn) { // An "unbuffered" query is a performance optimization // for large data sets. Mysql will lock the table in // question until all rows are read by the client. // It is unclear how this would be implemented on top // of Connector/J. return mysql_query(env, name, conn); } /** * Query an identifier that corresponds to this specific * connection. Mysql calls this integer identifier a * thread, but it is really a connection identifier. */ public static Value mysql_thread_id(Env env, @Optional Mysqli conn) { if (conn == null) conn = getConnection(env); return conn.thread_id(env); } //@todo mysql_list_processes() public static Value mysql_get_charset(Env env, @Optional Mysqli conn) { if (conn == null) { conn = getConnection(env); } return conn.get_charset(env); } public static boolean mysql_set_charset(Env env, StringValue charset, @Optional Mysqli conn) { if (conn == null) { conn = getConnection(env); } return conn.set_charset(env, charset); } private static Mysqli getConnection(Env env) { return getConnection(env, ""); } private static Mysqli getConnection(Env env, String db) { Mysqli conn = (Mysqli) env.getSpecialValue("caucho.mysql"); // php/1436 if (conn != null) return conn; conn = new MysqliResource(env, env.getEmptyString(), env.getEmptyString(), env.getEmptyString(), db, 3306, env.getEmptyString()); env.setSpecialValue("caucho.mysql", conn); return conn; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy