Skip to content

Commit

Permalink
RFC: expose mysql_connect_with_db() to PHP userland
Browse files Browse the repository at this point in the history
Summary:
The mysql protocol allows the selection of an initial database on connect time.
We currently have to call mysql_select_db() immediately after establishing a
connection. This change will allow us to set the db at connect time, to avoid
unnecessary round trips.

Test Plan:
I created a local instance of mysql and these databases:
create database foo;
create database bar;
create table bar_table ( message varchar(64) );
insert into bar_table (message) values ('You selected from bar_table in bar
db!');
create table foo_table ( message varchar(64) );
insert into foo_table (message) values ('You selected from foo_table in foo
db!');

Then I ran this test code:

$c = mysql_connect('127.0.0.1:3306', 'root');
echo $c . "<br/>";
mysql_select_db('foo') ."<br/>";
print_r( mysql_fetch_array(mysql_query('show tables'), $c) );
echo "<br/>";
print_r( mysql_fetch_array(mysql_query('select * from foo_table'), $c) );
echo "<hr/>";

$d = mysql_connect_with_db('127.0.0.1:3306', 'root', '', "bar");
echo $d . "<br/>";
print_r( mysql_fetch_array(mysql_query('show tables'), $d) );
echo "<br/>";
print_r( mysql_fetch_array(mysql_query('select * from bar_table'), $d) );

Expected result:
Resource id facebook#1
Array ( [Tables_in_foo] => foo_table )
Array ( [message] => You selected from foo_table in foo db! )
Resource id facebook#2
Array ( [0] => bar_table )
Array ( [0] => You selected from bar_table in bar db! )

DiffCamp Revision: 138364
Reviewed By: macvicar
Commenters: ps, rmcelroy, mcallaghan
CC: hphp-diffs@lists, rmcelroy, ps, macvicar, mcallaghan, cbueno
Revert Plan:
OK
  • Loading branch information
cbueno authored and macvicar committed Aug 1, 2010
1 parent 6e0d206 commit 329dca0
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 21 deletions.
20 changes: 20 additions & 0 deletions src/idl/mysql.idl.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@
'connect_timeout_ms' => array(Int32, '-1'),
'query_timeout_ms' => array(Int32, '-1')));


f('mysql_connect_with_db', Variant,
array('server' => array(String, 'null_string'),
'username' => array(String, 'null_string'),
'password' => array(String, 'null_string'),
'database' => array(String, 'null_string'),
'new_link' => array(Boolean, 'false'),
'client_flags' => array(Int32, '0'),
'connect_timeout_ms' => array(Int32, '-1'),
'query_timeout_ms' => array(Int32, '-1')));

f('mysql_pconnect_with_db', Variant,
array('server' => array(String, 'null_string'),
'username' => array(String, 'null_string'),
'password' => array(String, 'null_string'),
'database' => array(String, 'null_string'),
'client_flags' => array(Int32, '0'),
'connect_timeout_ms' => array(Int32, '-1'),
'query_timeout_ms' => array(Int32, '-1')));

f('mysql_set_charset', Variant,
array('charset' => String,
'link_identifier' => array(Variant, 'null')));
Expand Down
73 changes: 55 additions & 18 deletions src/runtime/ext/ext_mysql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,13 @@ static MYSQL *create_new_conn() {
}

MySQL::MySQL(const char *host, int port, const char *username,
const char *password)
const char *password, const char *database)
: m_port(port), m_last_error_set(false), m_last_errno(0),
m_xaction_count(0) {
if (host) m_host = host;
if (username) m_username = username;
if (password) m_password = password;
if (database) m_database = database;

m_conn = create_new_conn();
}
Expand Down Expand Up @@ -257,7 +258,8 @@ void MySQL::close() {
}

bool MySQL::connect(CStrRef host, int port, CStrRef socket, CStrRef username,
CStrRef password, int client_flags, int connect_timeout) {
CStrRef password, CStrRef database,
int client_flags, int connect_timeout) {
if (m_conn == NULL) {
m_conn = create_new_conn();
}
Expand All @@ -271,9 +273,11 @@ bool MySQL::connect(CStrRef host, int port, CStrRef socket, CStrRef username,
IOStatusHelper io("mysql::connect", host.data(), port);
m_xaction_count = 0;
bool ret = mysql_real_connect(m_conn, host.data(), username.data(),
password.data(), NULL, port,
socket.empty() ? NULL : socket.data(),
client_flags);
password.data(),
(database.empty() ? NULL : database.data()),
port,
socket.empty() ? NULL : socket.data(),
client_flags);
if (ret && RuntimeOption::MySQLWaitTimeout > 0) {
String query("set session wait_timeout=");
query += String((int64)(RuntimeOption::MySQLWaitTimeout / 1000));
Expand All @@ -286,8 +290,8 @@ bool MySQL::connect(CStrRef host, int port, CStrRef socket, CStrRef username,
}

bool MySQL::reconnect(CStrRef host, int port, CStrRef socket, CStrRef username,
CStrRef password, int client_flags,
int connect_timeout) {
CStrRef password, CStrRef database,
int client_flags, int connect_timeout) {
if (m_conn == NULL) {
m_conn = create_new_conn();
if (connect_timeout >= 0) {
Expand All @@ -299,14 +303,18 @@ bool MySQL::reconnect(CStrRef host, int port, CStrRef socket, CStrRef username,
}
IOStatusHelper io("mysql::connect", host.data(), port);
return mysql_real_connect(m_conn, host.data(), username.data(),
password.data(), NULL, port, socket.data(),
client_flags);
password.data(),
(database.empty() ? NULL : database.data()),
port, socket.data(), client_flags);
}

if (!mysql_ping(m_conn)) {
if (RuntimeOption::EnableStats && RuntimeOption::EnableSQLStats) {
ServerStats::Log("sql.reconn_ok", 1);
}
if (!database.empty()) {
mysql_select_db(m_conn, database.data());
}
return true;
}

Expand All @@ -320,8 +328,9 @@ bool MySQL::reconnect(CStrRef host, int port, CStrRef socket, CStrRef username,
IOStatusHelper io("mysql::connect", host.data(), port);
m_xaction_count = 0;
return mysql_real_connect(m_conn, host.data(), username.data(),
password.data(), NULL, port, socket.data(),
client_flags);
password.data(),
(database.empty() ? NULL : database.data()),
port, socket.data(), client_flags);
}

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -489,8 +498,8 @@ static Variant php_mysql_field_info(CVarRef result, int field,
}

static Variant php_mysql_do_connect(String server, String username,
String password, int client_flags,
bool persistent,
String password, String database,
int client_flags, bool persistent,
int connect_timeout_ms,
int query_timeout_ms) {
if (connect_timeout_ms < 0) {
Expand All @@ -502,6 +511,7 @@ static Variant php_mysql_do_connect(String server, String username,
if (server.empty()) server = MySQL::GetDefaultServer();
if (username.empty()) username = MySQL::GetDefaultUsername();
if (password.empty()) password = MySQL::GetDefaultPassword();
if (database.empty()) database = MySQL::GetDefaultDatabase();

// server format: hostname[:port][:/path/to/socket]
String host, socket;
Expand Down Expand Up @@ -535,17 +545,17 @@ static Variant php_mysql_do_connect(String server, String username,
}

if (mySQL == NULL) {
mySQL = new MySQL(host, port, username, password);
mySQL = new MySQL(host, port, username, password, database);
ret = mySQL;
if (!mySQL->connect(host, port, socket, username, password,
client_flags, connect_timeout_ms)) {
database, client_flags, connect_timeout_ms)) {
mySQL->setLastError("mysql_connect");
return false;
}
} else {
ret = mySQL;
if (!mySQL->reconnect(host, port, socket, username, password,
client_flags, connect_timeout_ms)) {
database, client_flags, connect_timeout_ms)) {
mySQL->setLastError("mysql_connect");
return false;
}
Expand All @@ -568,7 +578,21 @@ Variant f_mysql_connect(CStrRef server /* = null_string */,
int client_flags /* = 0 */,
int connect_timeout_ms /* = -1 */,
int query_timeout_ms /* = -1 */) {
return php_mysql_do_connect(server, username, password, client_flags, false,
return php_mysql_do_connect(server, username, password, "",
client_flags, false,
connect_timeout_ms, query_timeout_ms);
}

Variant f_mysql_connect_with_db(CStrRef server /* = null_string */,
CStrRef username /* = null_string */,
CStrRef password /* = null_string */,
CStrRef database /* = null_string */,
bool new_link /* = false */,
int client_flags /* = 0 */,
int connect_timeout_ms /* = -1 */,
int query_timeout_ms /* = -1 */) {
return php_mysql_do_connect(server, username, password, database,
client_flags, false,
connect_timeout_ms, query_timeout_ms);
}

Expand All @@ -578,7 +602,20 @@ Variant f_mysql_pconnect(CStrRef server /* = null_string */,
int client_flags /* = 0 */,
int connect_timeout_ms /* = -1 */,
int query_timeout_ms /* = -1 */) {
return php_mysql_do_connect(server, username, password, client_flags, true,
return php_mysql_do_connect(server, username, password, "",
client_flags, true,
connect_timeout_ms, query_timeout_ms);
}

Variant f_mysql_pconnect_with_db(CStrRef server /* = null_string */,
CStrRef username /* = null_string */,
CStrRef password /* = null_string */,
CStrRef database /* = null_string */,
int client_flags /* = 0 */,
int connect_timeout_ms /* = -1 */,
int query_timeout_ms /* = -1 */) {
return php_mysql_do_connect(server, username, password, database,
client_flags, true,
connect_timeout_ms, query_timeout_ms);
}

Expand Down
24 changes: 21 additions & 3 deletions src/runtime/ext/ext_mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class MySQL : public SweepableResourceData {
static String GetDefaultSocket();
static String GetDefaultUsername() { return String();}
static String GetDefaultPassword() { return String();}
static String GetDefaultDatabase() { return String();}

/**
* A connection may be persistent across multiple HTTP requests.
Expand Down Expand Up @@ -88,7 +89,7 @@ class MySQL : public SweepableResourceData {

public:
MySQL(const char *host, int port, const char *username,
const char *password);
const char *password, const char *database);
~MySQL();
void setLastError(const char *func);
void close();
Expand All @@ -98,9 +99,9 @@ class MySQL : public SweepableResourceData {
virtual bool isResource() const { return m_conn != NULL;}

bool connect(CStrRef host, int port, CStrRef socket, CStrRef username,
CStrRef password, int client_flags, int connect_timeout);
CStrRef password, CStrRef database, int client_flags, int connect_timeout);
bool reconnect(CStrRef host, int port, CStrRef socket, CStrRef username,
CStrRef password, int client_flags, int connect_timeout);
CStrRef password, CStrRef database, int client_flags, int connect_timeout);

MYSQL *get() { return m_conn;}

Expand All @@ -112,6 +113,7 @@ class MySQL : public SweepableResourceData {
int m_port;
std::string m_username;
std::string m_password;
std::string m_database;
bool m_last_error_set;
int m_last_errno;
std::string m_last_error;
Expand Down Expand Up @@ -218,6 +220,22 @@ Variant f_mysql_pconnect(CStrRef server = null_string,
int connect_timeout_ms = -1,
int query_timeout_ms = -1);

Variant f_mysql_connect_with_db(CStrRef server = null_string,
CStrRef username = null_string,
CStrRef password = null_string,
CStrRef database = null_string,
bool new_link = false,
int client_flags = 0,
int connect_timeout_ms = -1,
int query_timeout_ms = -1);
Variant f_mysql_pconnect_with_db(CStrRef server = null_string,
CStrRef username = null_string,
CStrRef password = null_string,
CStrRef database = null_string,
int client_flags = 0,
int connect_timeout_ms = -1,
int query_timeout_ms = -1);

String f_mysql_escape_string(CStrRef unescaped_string);

Variant f_mysql_real_escape_string(CStrRef unescaped_string,
Expand Down
10 changes: 10 additions & 0 deletions src/runtime/ext/profile/extprofile_mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ inline Variant x_mysql_pconnect(CStrRef server = null_string, CStrRef username =
return f_mysql_pconnect(server, username, password, client_flags, connect_timeout_ms, query_timeout_ms);
}

inline Variant x_mysql_connect_with_db(CStrRef server = null_string, CStrRef username = null_string, CStrRef password = null_string, CStrRef database = null_string, bool new_link = false, int client_flags = 0, int connect_timeout_ms = -1, int query_timeout_ms = -1) {
FUNCTION_INJECTION_BUILTIN(mysql_connect_with_db);
return f_mysql_connect_with_db(server, username, password, database, new_link, client_flags, connect_timeout_ms, query_timeout_ms);
}

inline Variant x_mysql_pconnect_with_db(CStrRef server = null_string, CStrRef username = null_string, CStrRef password = null_string, CStrRef database = null_string, int client_flags = 0, int connect_timeout_ms = -1, int query_timeout_ms = -1) {
FUNCTION_INJECTION_BUILTIN(mysql_pconnect_with_db);
return f_mysql_pconnect_with_db(server, username, password, database, client_flags, connect_timeout_ms, query_timeout_ms);
}

inline Variant x_mysql_set_charset(CStrRef charset, CVarRef link_identifier = null) {
FUNCTION_INJECTION_BUILTIN(mysql_set_charset);
return f_mysql_set_charset(charset, link_identifier);
Expand Down
Loading

0 comments on commit 329dca0

Please sign in to comment.