/* * Copyright (c) 1998-2011 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 Charles Reich */ package com.caucho.quercus.lib.db; import com.caucho.quercus.annotation.NotNull; import com.caucho.quercus.annotation.Optional; import com.caucho.quercus.annotation.Reference; import com.caucho.quercus.annotation.ReturnNullAsFalse; import com.caucho.quercus.env.*; import com.caucho.quercus.module.AbstractQuercusModule; import com.caucho.util.L10N; import com.caucho.util.Log; import java.util.logging.Level; import java.util.logging.Logger; /** * Quercus mysql routines. */ public class MysqliModule extends AbstractQuercusModule { private static final Logger log = Log.open(MysqliModule.class); private static final L10N L = new L10N(MysqliModule.class); public static final int MYSQLI_ASSOC = JdbcResultResource.FETCH_ASSOC; public static final int MYSQLI_NUM = JdbcResultResource.FETCH_NUM; public static final int MYSQLI_BOTH = JdbcResultResource.FETCH_BOTH; public static final int MYSQLI_USE_RESULT = 0x0; public static final int MYSQLI_STORE_RESULT = 0x1; // Used by mysqli_fetch_field. public static final int NOT_NULL_FLAG = 0x1; public static final int PRI_KEY_FLAG = 0x2; public static final int UNIQUE_KEY_FLAG = 0x4; public static final int MULTIPLE_KEY_FLAG = 0x8; public static final int BLOB_FLAG = 0x10; public static final int UNSIGNED_FLAG = 0x20; public static final int ZEROFILL_FLAG = 0x40; public static final int BINARY_FLAG = 0x80; // Sent to new clients public static final int ENUM_FLAG = 0x100; public static final int AUTO_INCREMENT_FLAG = 0x200; public static final int TIMESTAMP_FLAG = 0x400; public static final int SET_FLAG = 0x800; public static final int NUM_FLAG = 0x8000; public static final int PART_KEY_FLAG = 0x4000; //Intern: Part of some key??? public static final int GROUP_FLAG = 0x8000; //Intern: Group field??? public static final int UNIQUE_FLAG = 0x10000; //Intern: Used by sql_yacc??? public static final int BINCMP_FLAG = 0x20000; //Intern: Used by sql_yacc??? // The following are numerical respresentations // of types returned by mysqli_fetch_field. // These are defined in mysql's mysql_com.h header. public static final int MYSQLI_TYPE_DECIMAL = 0x0; public static final int MYSQLI_TYPE_TINY = 0x1; public static final int MYSQLI_TYPE_SHORT = 0x2; public static final int MYSQLI_TYPE_LONG = 0x3; public static final int MYSQLI_TYPE_FLOAT = 0x4; public static final int MYSQLI_TYPE_DOUBLE = 0x5; public static final int MYSQLI_TYPE_NULL = 0x6; public static final int MYSQLI_TYPE_TIMESTAMP = 0x7; public static final int MYSQLI_TYPE_LONGLONG = 0x8; public static final int MYSQLI_TYPE_INT24 = 0x9; public static final int MYSQLI_TYPE_DATE = 0xA; public static final int MYSQLI_TYPE_TIME = 0xB; public static final int MYSQLI_TYPE_DATETIME = 0xC; public static final int MYSQLI_TYPE_YEAR = 0xD; public static final int MYSQLI_TYPE_NEWDATE = 0xE; // Mysql defines the constant MYSQL_TYPE_VARCHAR = 0xF // but there is no MYSQLI_TYPE_VARCHAR flag. public static final int MYSQLI_TYPE_BIT = 0x10; public static final int MYSQLI_TYPE_NEWDECIMAL = 0xF6; public static final int MYSQLI_TYPE_ENUM = 0xF7; public static final int MYSQLI_TYPE_SET = 0xF8; public static final int MYSQLI_TYPE_TINY_BLOB = 0xF9; public static final int MYSQLI_TYPE_MEDIUM_BLOB = 0xFA; public static final int MYSQLI_TYPE_LONG_BLOB = 0xFB; public static final int MYSQLI_TYPE_BLOB = 0xFC; public static final int MYSQLI_TYPE_VAR_STRING = 0xFD; public static final int MYSQLI_TYPE_STRING = 0xFE; public static final int MYSQLI_TYPE_GEOMETRY = 0xFF; public static final int MYSQLI_TYPE_CHAR = MYSQLI_TYPE_TINY; public static final int MYSQLI_TYPE_INTERVAL = MYSQLI_TYPE_ENUM; public static final int MYSQL_CLIENT_COMPRESS = (1 << 5); // The next constant is NOT exported by this module, // but the PHP documentation states that 128 can be passed // in the client_flags parameter to mysql_connect(). // This flag will be ignored by Mysqli.connectImpl(). private static final int MYSQL_CLIENT_LOCAL_FILES = (1 << 7); public static final int MYSQL_CLIENT_IGNORE_SPACE = (1 << 8); public static final int MYSQL_CLIENT_INTERACTIVE = (1 << 10); public static final int MYSQL_CLIENT_SSL = (1 << 11); // mysqli_options option flags public static final int MYSQLI_READ_DEFAULT_GROUP = 0x0; public static final int MYSQLI_READ_DEFAULT_FILE = 0x1; public static final int MYSQLI_OPT_CONNECT_TIMEOUT = 0x2; public static final int MYSQLI_OPT_LOCAL_INFILE = 0x3; public static final int MYSQLI_INIT_COMMAND = 0x4; public MysqliModule() { } /** * Returns true for the mysql extension. */ public String []getLoadedExtensions() { return new String[] { "mysqli" }; } /** * Returns the number of affected rows. */ public static int mysqli_affected_rows(@NotNull Mysqli conn) { if (conn == null) return -1; return conn.affected_rows(); } /** * Turns auto-commit on or off. */ public static boolean mysqli_autocommit(@NotNull Mysqli conn, boolean mode) { if (conn == null) return false; return conn.autocommit(mode); } /** * Deprecated alias for {@link #mysqli_stmt_bind_param}. */ public static boolean mysqli_bind_param(Env env, @NotNull MysqliStatement stmt, StringValue types, @Reference Value[] params) { return mysqli_stmt_bind_param(env, stmt, types, params); } /** * Commits the current transaction for the supplied connection. * * returns true on success or false on failure */ public static boolean mysqli_commit(@NotNull Mysqli conn) { if (conn == null) return false; return conn.commit(); } /** * Returns the client encoding. */ public static Value mysqli_character_set_name(Env env, @NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return conn.character_set_name(env); } /** * Alias for {@link #mysqli_character_set_name}. */ public static Value mysqli_client_encoding(Env env, @NotNull Mysqli conn) { return mysqli_character_set_name(env, conn); } /** * Closes a connection. */ public static boolean mysqli_close(Env env, @NotNull Mysqli conn) { if (conn == null) return false; else if (! conn.isConnected()) { env.warning(L.l("no MySQLi-Link resource supplied")); return false; } return conn.close(env); } /** * Returns a new connection. */ @ReturnNullAsFalse public static Mysqli mysqli_connect(Env env, @Optional("localhost") StringValue host, @Optional StringValue userName, @Optional StringValue password, @Optional String dbname, @Optional("3306") int port, @Optional StringValue socket) throws IllegalStateException { Mysqli mysqli = new Mysqli(env, host, userName, password, dbname, port, socket); if (! mysqli.isConnected()) return null; return mysqli; } /** * Returns an error code value for the last call to mysqli_connect(), * 0 for no previous error. */ public static int mysqli_connect_errno(Env env) { Value value = (Value) env.getSpecialValue("mysqli.connectErrno"); if (value != null) return value.toInt(); else return 0; } /** * Returns an error description for the last call to mysqli_connect(), * "" for no previous error. */ public static StringValue mysqli_connect_error(Env env) { Object error = env.getSpecialValue("mysqli.connectError"); if (error != null) return env.createString(error.toString()); else return env.getEmptyString(); } /** * Seeks the specified row. * * @param env the PHP executing environment * @param result the mysqli_result * @param rowNumber the row offset * @return true on success or false if the row number * does not exist. NULL is returned if an error occurred. */ public static Value mysqli_data_seek(Env env, @NotNull MysqliResult result, int rowNumber) { if (result == null) return NullValue.NULL; if (result.seek(env, rowNumber)) { return BooleanValue.TRUE; } else { env.warning(L.l( "Offset {0} is invalid for MySQL (or the query data is unbuffered)", rowNumber)); return BooleanValue.FALSE; } } /** * Returns the error code for the most recent function call, * 0 for no error. */ public static Value mysqli_errno(@NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return LongValue.create(conn.errno()); } /** * Alias for {@link #mysqli_real_escape_string} */ public static Value mysqli_escape_string(Env env, @NotNull Mysqli conn, StringValue unescapedString) { return mysqli_real_escape_string(env, conn, unescapedString); } /** * Deprecated alias for {@link #mysqli_stmt_fetch}. */ public static Value mysqli_fetch(Env env, MysqliStatement stmt) { return mysqli_stmt_fetch(env, stmt); } /** * Returns the field metadata. * */ public static Value mysqli_fetch_field_direct(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return BooleanValue.FALSE; return result.fetch_field_direct(env, fieldOffset); } /** * Returns the field metadata. */ public static Value mysqli_fetch_field(Env env, @NotNull MysqliResult result) { if (result == null) return BooleanValue.FALSE; return result.fetch_field(env); } /** * Returns an array of field metadata. */ public static Value mysqli_fetch_fields(Env env, @NotNull MysqliResult result) { if (result == null) return BooleanValue.FALSE; return result.fetch_fields(env); } /** * Returns an array of integers respresenting the size of each column * FALSE if an error occurred. * * @param env the PHP executing environment * @param result the mysqli_result * @return true on success or false if an error occurred. * NULL is returned if result is null. */ public static Value mysqli_fetch_lengths(Env env, @NotNull MysqliResult result) { if (result == null) return NullValue.NULL; return result.fetch_lengths(); } /** * Seeks to the specified field offset. * If the next call to mysql_fetch_field() doesn't include * a field offset, the field offset specified in * mysqli_field_seek() will be returned. */ public static boolean mysqli_field_seek(Env env, @NotNull MysqliResult result, int fieldOffset) { if (result == null) return false; return result.field_seek(env, fieldOffset); } /** * Returns the position of the field cursor used for the last * mysqli_fetch_field() call. This value can be used as an * argument to mysqli_field_seek() */ public static int mysqli_field_tell(Env env, @NotNull MysqliResult result) { if (result == null) return -1; return result.field_tell(env); } /** * Frees a mysqli result */ public static boolean mysqli_free_result(@NotNull MysqliResult result) { if (result == null) return false; result.close(); return true; } /** * 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 mysqli_insert_id(Env env, @NotNull Mysqli conn) { if (conn == null) return BooleanValue.FALSE; return conn.insert_id(env); } /** * Returns the number of fields from specified result set. */ public static Value mysqli_num_fields(@NotNull MysqliResult result) { if (result == null) return NullValue.NULL; return LongValue.create(result.num_fields()); } /** * Executes one or multiple queires which are * concatenated by a semicolon. */ public static boolean mysqli_multi_query(Env env, @NotNull Mysqli conn, StringValue query) { if (conn == null) return false; return conn.multi_query(env, query); } /** * Indicates if one or more result sets are available from * a previous call to mysqli_multi_query. */ public static boolean mysqli_more_results(@NotNull Mysqli conn) { if (conn == null) return false; return conn.more_results(); } /** * Prepares next result set from a previous call to * mysqli_multi_query. */ public static boolean mysqli_next_result(@NotNull Mysqli conn) { if (conn == null) return false; return conn.next_result(); } /** * Returns the error code for the prepared statement. */ public static int mysqli_stmt_errno(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return 0; return stmt.errno(); } /** * Returns the error message for the prepared statement. */ public static StringValue mysqli_stmt_error(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return env.getEmptyString(); return stmt.error(env); } /** * Returns the most recent error. */ public static Value mysqli_error(Env env, @NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return conn.error(env); } /** * Returns the number of columns for the most recent query. */ public static int mysqli_field_count(@NotNull Mysqli conn) { if (conn == null) return 0; return conn.field_count(); } /** * Returns a row for the result. */ @ReturnNullAsFalse public static ArrayValue mysqli_fetch_array(Env env, @NotNull MysqliResult result, @Optional("MYSQLI_BOTH") int type) { if (result == null) return null; return result.fetch_array(env, type); } /** * Returns an associative array from the result. */ @ReturnNullAsFalse public static ArrayValue mysqli_fetch_assoc(Env env, @NotNull MysqliResult result) { if (result == null) return null; return result.fetch_assoc(env); } /** * Returns a row for the result. Return NULL if there are no more rows. */ public static ArrayValue mysqli_fetch_row(Env env, @NotNull MysqliResult result) { if (result == null) return null; return result.fetch_row(env); } /** * Returns an object with properties that correspond * to the fetched row and moves the data pointer ahead. * * @param env the PHP executing environment * @param result the mysqli_result * @return an object that corresponds to the fetched * row or NULL if there are no more rows in resultset */ public static Value mysqli_fetch_object(Env env, @NotNull MysqliResult result) { if (result == null) return NullValue.NULL; return result.fetch_object(env); } /** * Returns the MySQL client version. */ public static StringValue mysqli_get_client_info(Env env) { return Mysqli.getClientInfo(env); } /** * Returns a number that represents the MySQL client library * version in format: * * main_version*10000 + minor_version*100 + sub_version. * * For example 4.1.0 is returned as 40100. */ public static int mysqli_get_client_version(Env env) { return Mysqli.infoToVersion( mysqli_get_client_info(env).toString()); } /** * Returns a string describing the type of MySQL * connection in use. */ public static Value mysqli_get_host_info(Env env, @NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return conn.get_host_info(env); } /** * Return protocol number, for example 10. */ public static Value mysqli_get_proto_info(@NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return LongValue.create(conn.get_proto_info()); } /** * Returns the MySQL server version. */ public static Value mysqli_get_server_info(Env env, @NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; if (conn.isConnected()) return conn.get_server_info(env); else return NullValue.NULL; } /** * Returns a number that represents the MySQL server version. */ public static Value mysqli_get_server_version(@NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return LongValue.create(conn.get_server_version()); } /** * Returns the number of rows in the result set. * * @param env the PHP executing environment * @param result the mysqli_result * @return the number of rows in the result set * or NULL, if an error occurred */ public static Value mysqli_num_rows(Env env, @NotNull MysqliResult result) { if (result == null) return NullValue.NULL; return LongValue.create(result.num_rows()); } /** * Sets the options for a connection. */ public static boolean mysqli_options(@NotNull Mysqli mysqli, int option, Value value) { if (mysqli == null) return false; return mysqli.options(option, value); } /** * Alias of {@link #mysqli_options}. */ public static boolean mysqli_set_opt(@NotNull Mysqli mysqli, int option, Value value) { return mysqli_options(mysqli, option, value); } /** * Alias of {@link #mysqli_stmt_param_count}. */ public static int mysqli_param_count(Env env, @NotNull MysqliStatement stmt) { return mysqli_stmt_param_count(env, stmt); } /** * Rolls back the current transaction for the * connection. * * @return true on success or false on failure. */ public static boolean mysqli_rollback(@NotNull Mysqli conn) { if (conn == null) return false; return conn.rollback(); } /** * Sets the character set for a conneciton. */ public static boolean mysqli_set_charset(@NotNull Mysqli mysqli, String charset) { if (mysqli == null) return false; return mysqli.set_charset(charset); } /** * Returns the number of rows. */ public static Value mysqli_stmt_num_rows(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return BooleanValue.FALSE; return stmt.num_rows(env); } /** * Returns an integer representing the number of parameters * or -1 if no query has been prepared. */ public static int mysqli_stmt_param_count(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return -1; return stmt.param_count(env); } /** * Prepares a statment with a query. */ public static boolean mysqli_stmt_prepare(Env env, @NotNull MysqliStatement stmt, StringValue query) { if (stmt == null) return false; return stmt.prepare(env, query); } /** * Resets a statment. */ public static boolean mysqli_stmt_reset(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return false; return stmt.reset(env); } /** * Returns result information for metadata */ @ReturnNullAsFalse public static JdbcResultResource mysqli_stmt_result_metadata(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return null; return stmt.result_metadata(env); } /** * Returns an error string. */ public static Value mysqli_sqlstate(Env env, @NotNull Mysqli conn) { if (conn == null) return NullValue.NULL; return conn.sqlstate(env); } /** * Returns an error string. */ public static Value mysqli_stmt_sqlstate(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return NullValue.NULL; return stmt.sqlstate(env); } /** * Saves the result. */ public static boolean mysqli_stmt_store_result(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return false; return stmt.store_result(env); } /** * Transfers the result set from the last query on the * database connection represented by conn. * * Used in conjunction with {@link #mysqli_multi_query} */ @ReturnNullAsFalse public static JdbcResultResource mysqli_store_result(Env env, @NotNull Mysqli conn) { if (conn == null) return null; return conn.store_result(env); } /** * Initiate a result set retrieval. This method is useful when * dealing with multiple results from a multi-query. Currently, * unbuffered results are not supported so this method always * uses buffered results. */ @ReturnNullAsFalse public static JdbcResultResource mysqli_use_result(Env env, @NotNull Mysqli conn) { if (conn == null) return null; return conn.use_result(env); } /** * Returns the number of warnings from the last query * in the connection object. * * @return number of warnings */ public static int mysqli_warning_count(Env env, @NotNull Mysqli conn) { if (conn == null) return 0; return conn.warning_count(env); } /** * Checks if the connection is still valid */ public static boolean mysqli_ping(Env env, @NotNull Mysqli conn) { if (conn == null) return false; return conn.ping(env); } /** * Executes a query and returns the result. * */ public static Value mysqli_query( Env env, @NotNull Mysqli conn, StringValue sql, @Optional("MYSQLI_STORE_RESULT") int resultMode) { // ERRATUM: <i>resultMode</i> is ignored, MYSQLI_USE_RESULT would represent // an unbuffered query, but that is not supported. Value value = query(env, conn, sql); if (value == null) { return BooleanValue.FALSE; } return value; } private static Value query(Env env, Mysqli conn, StringValue sql) { Value value = null; try { value = conn.query(env, sql, MYSQLI_STORE_RESULT); } catch (Exception e) { log.log(Level.FINE, e.toString(), e); } if (value == null) { return BooleanValue.FALSE; } return value; } /** * Connects to the database. */ public static boolean mysqli_real_connect( Env env, @NotNull Mysqli mysqli, @Optional("localhost") StringValue host, @Optional StringValue userName, @Optional StringValue password, @Optional StringValue dbname, @Optional("3306") int port, @Optional StringValue socket, @Optional int flags) { if (mysqli == null) return false; return mysqli.real_connect(env, host, userName, password, dbname, port, socket, flags); } /** * Escapes the following special character in unescapedString. * * @return the escaped string. */ public static Value mysqli_real_escape_string(Env env, @NotNull Mysqli conn, StringValue unescapedString) { if (conn == null) return NullValue.NULL; if (unescapedString.length() == 0) return env.getEmptyString(); StringBuilder buf = new StringBuilder(); escapeString(buf, unescapedString.toString()); return env.createString(buf.toString()); } static void escapeString(StringBuilder buf, String unescapedString) { char c; final int strLength = unescapedString.length(); for (int i = 0; i < strLength; i++) { c = unescapedString.charAt(i); switch (c) { case '\u0000': buf.append('\\'); buf.append('\u0000'); break; case '\n': buf.append('\\'); buf.append('n'); break; case '\r': buf.append('\\'); buf.append('r'); break; case '\\': buf.append('\\'); buf.append('\\'); break; case '\'': buf.append('\\'); buf.append('\''); break; case '"': buf.append('\\'); buf.append('\"'); break; case '\032': buf.append('\\'); buf.append('Z'); break; default: buf.append(c); break; } } } /** * Execute an single query against the database * whose result can then be retrieved * or stored using the mysqli_store_result() * or mysqli_use_result() functions. */ public static boolean mysqli_real_query(Env env, @NotNull Mysqli conn, StringValue query) { if (conn == null) return false; return conn.real_query(env, query); } /** * Execute a query with arguments and return a result. */ static Value mysqli_query(Env env, Mysqli conn, StringValue query, Object ... args) { StringBuilder buf = new StringBuilder(); int size = query.length(); int argIndex = 0; for (int i = 0; i < size; i++) { char ch = buf.charAt(i); if (ch == '?') { Object arg = args[argIndex++]; if (arg == null) throw new IllegalArgumentException( L.l("argument `{0}' cannot be null", arg)); buf.append('\''); escapeString(buf, String.valueOf(arg)); buf.append('\''); } else buf.append(ch); } return query(env, conn, env.createString(buf.toString())); } /** * Select the database for a connection. */ public static boolean mysqli_select_db(Mysqli conn, String dbName) { if (conn == null) return false; return conn.select_db(dbName); } /** * Returns a string with the status of the connection * or FALSE if error. */ public static Value mysqli_stat(Env env, @NotNull Mysqli conn) { if (conn == null) return BooleanValue.FALSE; return conn.stat(env); } /** * Return the number of rows affected by an INSERT, UPDATE, or DELETE * query. Unlike mysqli_stmt_num_rows(), this method does not return * the number of rows matched by a SELECT query. */ public static int mysqli_stmt_affected_rows(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return -1; if (stmt.errno() != 0) return -1; return stmt.affected_rows(env); } /** * Binds variables for the parameter markers * in SQL statement that was passed to * {@link #mysqli_prepare}. * * Type specification chars: * <dl> * <dt>i<dd>corresponding variable has type integer; * <dt>d<dd>corresponding variable has type double; * <dt>b<dd>corresponding variable is a blob and will be sent in packages * <dt>s<dd>corresponding variable has type string * (which really means all other types); * </dl> */ public static boolean mysqli_stmt_bind_param(Env env, @NotNull MysqliStatement stmt, StringValue types, @Reference Value[] params) { if (stmt == null) return false; return stmt.bind_param(env, types, params); } /** * Binds outparams to result set. */ public static boolean mysqli_stmt_bind_result(Env env, @NotNull MysqliStatement stmt, @Reference Value[] outParams) { if (stmt == null) return false; return stmt.bind_result(env, outParams); } /** * Closes the statement. */ public boolean mysql_stmt_close(MysqliStatement stmt) { if (stmt == null) return false; stmt.close(); return true; } /** * Seeks to a given result. * * @return NULL on sucess or FALSE on failure */ public Value mysqli_stmt_data_seek(Env env, @NotNull MysqliStatement stmt, int offset) { if (stmt == null) return BooleanValue.FALSE; return stmt.data_seek(env, offset); } /** * Returns the error number. */ public int mysql_stmt_errno(Env env, MysqliStatement stmt) { if (stmt != null) return stmt.errno(); else return 0; } /** * Returns a descrption of the error or an empty strng for no error. */ public StringValue mysql_stmt_error(Env env, MysqliStatement stmt) { if (stmt == null) return null; return stmt.error(env); } /** * Executes a statement that has been prepared using {@link #mysqli_prepare}. * * @return true on success or false on failure */ public static boolean mysqli_stmt_execute(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return false; return stmt.execute(env); } /** * Fetch results from a prepared statement. * @return true on success, false on error, null if no more rows. */ public static Value mysqli_stmt_fetch(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return BooleanValue.FALSE; return stmt.fetch(env); } /** * Frees the result. */ public static boolean mysqli_stmt_free_result(Env env, MysqliStatement stmt) { if (stmt == null) return false; stmt.free_result(env); return true; } /** * Deprecated alias for {@link #mysqli_stmt_bind_result}. */ public static boolean mysqli_bind_result(Env env, @NotNull MysqliStatement stmt, @Reference Value[] outParams) { return mysqli_stmt_bind_result(env, stmt, outParams); } /** * Changes the user and database. */ public static boolean mysqli_change_user(@NotNull Mysqli mysqli, String user, String password, String db) { if (mysqli == null) return false; return mysqli.change_user(user, password, db); } /** * Deprecated alias for {@link #mysqli_stmt_execute}. */ public static boolean mysqli_execute(Env env, @NotNull MysqliStatement stmt) { return mysqli_stmt_execute(env, stmt); } /** * Deprecated alias for {@link #mysqli_stmt_result_metadata}. */ @ReturnNullAsFalse public static JdbcResultResource mysqli_get_metadata( Env env, @NotNull MysqliStatement stmt) { return mysqli_stmt_result_metadata(env, stmt); } /** * Creates a new mysqli object. */ public static Mysqli mysqli_init(Env env) { return new Mysqli(env); } /** * Prepares a statement. */ @ReturnNullAsFalse public static MysqliStatement mysqli_prepare(Env env, @NotNull Mysqli conn, StringValue query) { if (conn == null) return null; return conn.prepare(env, query); } /** * Closes a statement. */ public static boolean mysqli_stmt_close(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return false; return stmt.close(env); } /** * Returns a statement for use with {@link #mysqli_stmt_prepare} */ public static MysqliStatement mysqli_stmt_init(Env env, @NotNull Mysqli conn) { if (conn == null) return null; return conn.stmt_init(env); } /** * Get information about the most recent query. */ public static Value mysqli_info(Env env, @Optional Mysqli conn) { if (conn == null) return null; return conn.info(env); } /** * Undocumented */ public static int mysqli_stmt_field_count(Env env, @NotNull MysqliStatement stmt) { if (stmt == null) return -1; return stmt.field_count(env); } /** * 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 mysqli_thread_id(Env env, @NotNull Mysqli conn) { if (conn == null) return BooleanValue.FALSE; return conn.thread_id(env); } /** * Terminate a Mysql connection with the given thread id. * It should be possible to terminate any connection id * via this method. In practice, only the mysqli_thread_id * API returns a thread id, so only the id of the current * thread can be looked up. */ public static boolean mysqli_kill(Env env, @NotNull Mysqli conn, int threadId) { if (conn == null) return false; return conn.kill(env, threadId); } // Undocumented // // mysqli_enable_reads_from_master // mysqli_disable_reads_from_master // mysqli_enable_rpl_parse // mysqli_disable_rpl_parse // mysqli_rpl_parse_enabled // mysqli_rpl_probe // mysqli_rpl_query_type // mysqli_embedded_server_start // mysqli_embedded_server_end // mysqli_get_charset // mysqli_master_query // mysqli_send_query // mysqli_server_end // mysqli_server_init // mysqli_set_local_infile_default // mysqli_set_local_infile_handler // mysqli_slave_query // mysqli_stmt_attr_get // mysqli_stmt_attr_set // mysqli_stmt_get_warnings // mysqli_stmt_insert_id // Unimplemented // //@todo mysqli_debug //@todo mysqli_dump_debug_info //@todo mysqli_kill //@todo mysqli_report //@todo mysqli_send_long_data (alias for mysqli_stmt_send_long_data) //@todo mysqli_set_charset //@todo mysqli_ssl_set //@todo mysqli_stmt_send_long_data //@todo mysqli_thread_safe }