summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/mysql.php74
-rw-r--r--tests/MySqlShimTest.php331
2 files changed, 353 insertions, 52 deletions
diff --git a/lib/mysql.php b/lib/mysql.php
index ecfb767..e7a2a57 100644
--- a/lib/mysql.php
+++ b/lib/mysql.php
@@ -1,6 +1,11 @@
<?php
namespace {
if (!function_exists('\mysql_connect')) {
+ define('MYSQL_CLIENT_COMPRESS', MYSQLI_CLIENT_COMPRESS);
+ define('MYSQL_CLIENT_IGNORE_SPACE', MYSQLI_CLIENT_IGNORE_SPACE);
+ define('MYSQL_CLIENT_INTERACTIVE', MYSQLI_CLIENT_INTERACTIVE);
+ define('MYSQL_CLIENT_SSL', MYSQLI_CLIENT_SSL);
+
function mysql_connect(
$hostname = null,
$username = null,
@@ -12,21 +17,46 @@ namespace {
trigger_error('Argument $new is no longer supported in PHP > 7', E_USER_WARNING);
}
+ $hash = sha1($hostname . $username . $flags);
+ if ($hostname{1} != ':' && isset(\Dshafik\MySQL::$connections[$hash])) {
+ \Dshafik\MySQL::$last_connection = \Dshafik\MySQL::$connections[$hash]['conn'];
+ \Dshafik\MySQL::$connections[$hash]['refcount'] += 1;
+ return \Dshafik\MySQL::$connections[$hash]['conn'];
+ }
+
if ($flags === 0) {
- $conn = \Dshafik\MySQL::$last_connection = mysqli_connect($hostname, $username, $password);
+ \Dshafik\MySQL::$last_connection = $conn = mysqli_connect($hostname, $username, $password);
+ $conn->hash = $hash;
+ \Dshafik\MySQL::$connections[$hash] = ['refcount' => 1, 'conn' => $conn];
+
return $conn;
}
try {
- $conn = \Dshafik\MySQL::$last_connection = mysqli_init();
+ \Dshafik\MySQL::$last_connection = $conn = mysqli_init();
+
+ mysqli_real_connect(
+ $conn,
+ $hostname,
+ $username,
+ $password,
+ '',
+ null,
+ '',
+ $flags
+ );
- mysqli_options($conn, $flags);
+ if ($conn === false) {
+ return false;
+ }
- mysqli_real_connect($conn, $hostname, $username, $password);
+ $conn->hash = $hash;
+ \Dshafik\MySQL::$connections[$hash] = ['refcount' => 1, 'conn' => $conn];
return $conn;
} catch (\Throwable $e) {
- var_dump($e);
+ trigger_error($e->getMessage(), E_USER_WARNING);
+ return false;
}
}
@@ -49,10 +79,20 @@ namespace {
return false;
}
- $return = mysqli_close($link);
+ if (isset(\Dshafik\MySQL::$connections[$link->hash])) {
+ \Dshafik\MySQL::$connections[$link->hash]['refcount'] -= 1;
+ }
+
+ $return = true;
+ if (\Dshafik\MySQL::$connections[$link->hash]['refcount'] == 0) {
+ $return = mysqli_close($link);
+ unset(\Dshafik\MySQL::$connections[$link->hash]);
+ }
+
if ($isDefault) {
Dshafik\MySQL::$last_connection = null;
}
+
return $return;
}
@@ -62,7 +102,7 @@ namespace {
return mysqli_query(
$link,
- "USE " . mysqli_real_escape_string($link)
+ "USE " . mysqli_real_escape_string($link, $databaseName)
) !== false;
}
@@ -74,8 +114,11 @@ namespace {
function mysql_unbuffered_query($query, \mysqli $link = null)
{
$link = \Dshafik\MySQL::getConnection($link);
- mysqli_real_query($link, $query);
- return $link;
+ if (mysqli_real_query($link, $query)) {
+ return mysqli_use_result($link);
+ }
+
+ return false;
}
function mysql_db_query($databaseName, $query, \mysqli $link = null)
@@ -149,7 +192,11 @@ namespace {
function mysql_num_rows(\mysqli_result $result)
{
- return mysqli_num_rows($result);
+ $previous = error_reporting(0);
+ $rows = mysqli_num_rows($result);
+ error_reporting($previous);
+
+ return $rows;
}
function mysql_num_fields(\mysqli_result $result)
@@ -172,8 +219,12 @@ namespace {
return mysqli_fetch_assoc($result);
}
- function mysql_fetch_object(\mysqli_result $result, $class, array $params = []) /* : object|null */
+ function mysql_fetch_object(\mysqli_result $result, $class = null, array $params = []) /* : object|null */
{
+ if ($class == null) {
+ return mysqli_fetch_object($result);
+ }
+
return mysqli_fetch_object($result, $class, $params);
}
@@ -374,6 +425,7 @@ namespace {
namespace Dshafik {
class MySQL {
static public $last_connection = null;
+ static public $connections = [];
static public function getConnection($link = null, $func = null)
{
diff --git a/tests/MySqlShimTest.php b/tests/MySqlShimTest.php
index 4739558..35523cf 100644
--- a/tests/MySqlShimTest.php
+++ b/tests/MySqlShimTest.php
@@ -11,8 +11,6 @@
namespace Dshafik\MySQL\Tests;
-use function \mysql_connect;
-
class MySqlShimTest extends \PHPUnit_Framework_TestCase
{
static $host;
@@ -21,13 +19,8 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
public function test_mysql_connect()
{
- $mysql = mysql_connect(static::$host, 'root');
-
- $this->assertTrue(
- is_resource($mysql) && get_resource_type($mysql) == 'mysql link'
- ||
- $mysql instanceof \mysqli
- );
+ $mysql = \mysql_connect(static::$host, 'root');
+ $this->assertConnection($mysql);
}
/**
@@ -36,25 +29,98 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
*/
public function test_mysql_connect_fail()
{
- $mysql = mysql_connect(static::$host);
+ $mysql = \mysql_connect(static::$host);
+ }
+
+ /**
+ * @expectedException \PHPUnit_Framework_Error_Warning
+ * @expectedExceptionMessage Argument $new is no longer supported in PHP > 7
+ * @requires PHP 7.0.0
+ */
+ public function test_mysql_connect_new()
+ {
+ $mysql = \mysql_connect(static::$host, 'root', null, true);
+ }
+
+ public function test_mysql_connect_options()
+ {
+ $mysql = \mysql_connect(static::$host, 'root', null, false, MYSQL_CLIENT_COMPRESS);
+ $this->assertConnection($mysql);
+ }
+
+ /**
+ * @expectedException \PHPUnit_Framework_Error_Warning
+ * @expectedExceptionMessageRegExp /^mysql((i_real)?)_connect\(\): (\(HY000\/1045\): )?Access denied for user ''@'(.*?)' \(using password: NO\)$/
+ */
+ public function test_mysql_connect_options_fail()
+ {
+ \mysql_connect(static::$host, null, null, false, MYSQL_CLIENT_COMPRESS);
+ }
+
+ public function test_mysql_connect_multi()
+ {
+ $conn = \mysql_connect(static::$host, 'root');
+ $conn2 = \mysql_connect(static::$host, 'root');
+
+ $this->assertEquals($conn, $conn2);
+
+ $result = \mysql_query("SELECT CONNECTION_ID()", $conn);
+ $row = \mysql_fetch_row($result);
+ $id = $row[0];
+
+ $result = \mysql_query("SELECT CONNECTION_ID()", $conn2);
+ $row = \mysql_fetch_row($result);
+ $id2 = $row[0];
+
+ $this->assertEquals($id, $id2);
+ }
+
+ public function test_mysql_pconnect()
+ {
+ $conn = \mysql_pconnect(static::$host, 'root');
+
+ $result = \mysql_query("SELECT 'persistent'", $conn);
+ $row = \mysql_fetch_row($result);
+ $this->assertEquals('persistent', $row[0]);
+ }
- $this->assertFalse($mysql);
+ public function test_mysql_query_ddl()
+ {
+ $conn = \mysql_connect(static::$host, 'root');
+ $result = \mysql_query("CREATE DATABASE shim_test;");
+ $this->assertTrue($result);
+ $result = \mysql_select_db('shim_test');
+ $this->assertTrue($result);
+ $result = \mysql_query(
+ "CREATE TABLE testing (
+ id int AUTO_INCREMENT,
+ one varchar(255),
+ two varchar(255),
+ PRIMARY KEY (id)
+ );"
+ );
+ $this->assertTrue($result, \mysql_error());
+ }
+
+ public function test_mysql_query_insert()
+ {
+ $this->getConnection("mysql_shim");
+ $result = \mysql_query("INSERT INTO testing (one, two) VALUES ('1', '1'), ('2', '2'), ('3', '3'), ('4', '4')");
+
+ $this->assertTrue($result, \mysql_error());
}
public function test_mysql_query()
{
- \mysql_connect(static::$host, 'root');
+ $this->getConnection("mysql_shim");
$result = \mysql_query("SELECT VERSION()");
- $this->assertTrue(
- is_resource($result) && get_resource_type($result) == 'mysql result'
- || $result instanceof \mysqli_result
- );
+ $this->assertResult($result);
}
public function test_mysql_query_nodata()
{
- \mysql_connect(static::$host, 'root');
+ $this->getConnection("mysql_shim");
$result = \mysql_query("SET @test = 'foo'");
$this->assertTrue($result);
@@ -62,50 +128,147 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
public function test_mysql_query_fail()
{
- \mysql_connect(static::$host, 'root');
+ $this->getConnection("mysql_shim");
$result = \mysql_query("SELECT VERSION(");
$this->assertFalse($result);
}
- public function test_mysql_fetch_array()
+ public function test_mysql_unbuffered_query()
{
- \mysql_connect(static::$host, 'root');
+ $this->getConnection("mysql_shim");
- $result = \mysql_query("SELECT 'test' AS col");
+ $result = \mysql_unbuffered_query("SELECT one, two FROM testing LIMIT 4");
+ $this->assertResult($result);
+ $i = 0;
+ while ($row = \mysql_fetch_assoc($result)) {
+ $i++;
+ }
+ $this->assertEquals(4, $i);
- $row = \mysql_fetch_array($result);
- $this->assertTrue(is_array($row));
- $this->assertArrayHasKey(0, $row);
- $this->assertEquals($row[0], 'test');
- $this->assertArrayHasKey('col', $row);
- $this->assertEquals($row['col'], 'test');
+ $result = \mysql_query("SELECT one, two FROM testing LIMIT 4");
+ $this->assertResult($result);
}
- public function test_mysql_fetch_array_multirow()
+ public function test_mysql_unbuffered_query_fail()
{
- \mysql_connect(static::$host, 'root');
+ $this->getConnection();
+
+ $result = \mysql_unbuffered_query("SELECT VERSION(");
+ $this->assertFalse($result);
+ }
- $result = \mysql_query("SHOW DATABASES");
+ public function test_mysql_unbuffered_query_num_rows()
+ {
+ $this->getConnection("mysql_shim");
+
+ \mysql_query(
+ "CREATE TABLE largetest (
+ id int AUTO_INCREMENT,
+ one varchar(255),
+ two varchar(255),
+ PRIMARY KEY (id)
+ );"
+ );
- while ($row = \mysql_fetch_array($result)) {
- $this->assertTrue(is_array($row));
- $this->assertArrayHasKey(0, $row);
- $this->assertTrue(in_array($row[0], ["information_schema", "mysql", "performance_schema", "sys"]));
- $this->assertArrayHasKey('Database', $row);
- $this->assertTrue(in_array($row['Database'], ["information_schema", "mysql", "performance_schema", "sys"]));
+ $result = \mysql_unbuffered_query("SELECT one, two FROM testing");
+ $this->assertResult($result);
+ $this->assertEquals(0, \mysql_num_rows($result));
+ \mysql_free_result($result);
+ }
+
+ public function test_mysql_unbuffered_query_close_legacy()
+ {
+ if (!version_compare(PHP_VERSION, '7.0.0', '<')) {
+ $this->markTestSkipped("PHP < 7.0.0 is required");
+ }
+
+ $conn = $this->getConnection("mysql_shim");
+
+ \mysql_query(
+ "CREATE TABLE largetest (
+ id int AUTO_INCREMENT,
+ one varchar(255),
+ two varchar(255),
+ PRIMARY KEY (id)
+ );"
+ );
+
+ $result = \mysql_unbuffered_query("SELECT one, two FROM testing");
+ $this->assertResult($result);
+ try {
+ \mysql_close($conn);
+ } catch (\PHPUnit_Framework_Error_Notice $e) {
+ $this->assertEquals(
+ "mysql_close(): Function called without first fetching all rows from a previous unbuffered query",
+ $e->getMessage()
+ );
}
}
- public function test_mysql_num_rows()
+ /**
+ * @requires PHP 7.0.0
+ */
+ public function test_mysql_unbuffered_query_close()
{
- \mysql_connect(static::$host, 'root');
+ $conn = $this->getConnection("mysql_shim");
+
+ \mysql_query(
+ "CREATE TABLE largetest (
+ id int AUTO_INCREMENT,
+ one varchar(255),
+ two varchar(255),
+ PRIMARY KEY (id)
+ );"
+ );
+
+ $result = \mysql_unbuffered_query("SELECT one, two FROM testing");
+ $this->assertResult($result);
+ \mysql_close($conn);
+ }
- $result = \mysql_query("SHOW DATABASES");
+ /**
+ * @dataProvider mysql_fetch_DataProvider
+ */
+ public function test_mysql_fetch($function, $results)
+ {
+ $this->getConnection("mysql_shim");
+ $result = \mysql_query("SELECT one, two FROM testing");
+ $this->assertResult($result);
+
+ $this->assertEquals(sizeof($results), \mysql_num_rows($result));
+
+ $i = 0;
+ while ($row = $function($result)) {
+ $this->assertEquals($results[$i], $row);
+ $i++;
+ }
+
+ $this->assertEquals(sizeof($results), $i);
+ }
+
+ public function test_mysql_num_rows()
+ {
+ $this->getConnection("mysql_shim");
+
+ $result = \mysql_query("SELECT * FROM testing");
+ $this->assertResult($result);
$this->assertEquals(4, \mysql_num_rows($result));
}
+ public function test_mysql_affected_rows()
+ {
+ $this->getConnection("mysql_shim");
+
+ $result = \mysql_query("UPDATE testing SET one = one + 1, two = two + 1 ORDER BY one DESC LIMIT 4");
+ $this->assertTrue($result);
+ $this->assertEquals(4, \mysql_affected_rows());
+ $result = \mysql_query("UPDATE testing SET one = one - 1, two = two - 1 ORDER BY one DESC LIMIT 4");
+ $this->assertTrue($result);
+ $this->assertEquals(4, \mysql_affected_rows());
+ }
+
public function test_mysql_close()
{
\mysql_connect(static::$host, 'root');
@@ -118,7 +281,7 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
*/
public function test_mysql_close_fail()
{
- $this->assertFalse(\mysql_close());
+ \mysql_close();
}
public function tearDown()
@@ -136,7 +299,6 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
}
if (!empty($dm)) {
-
fwrite(STDERR, "=> Starting Docker Machine\n");
exec($dm . ' create -d virtualbox mysql-shim');
exec($dm . ' start mysql-shim');
@@ -201,4 +363,91 @@ class MySqlShimTest extends \PHPUnit_Framework_TestCase
}
fwrite(STDERR, "Done\n");
}
+
+ public function mysql_fetch_DataProvider()
+ {
+ $numeric = [
+ ['1', '1'],
+ ['2', '2'],
+ ['3', '3'],
+ ['4', '4'],
+ ];
+
+ $assoc = [
+ ['one' => '1', 'two' => '1'],
+ ['one' => '2', 'two' => '2'],
+ ['one' => '3', 'two' => '3'],
+ ['one' => '4', 'two' => '4'],
+ ];
+
+ $array = [
+ ['1', '1', 'one' => '1', 'two' => '1'],
+ ['2', '2', 'one' => '2', 'two' => '2'],
+ ['3', '3', 'one' => '3', 'two' => '3'],
+ ['4', '4', 'one' => '4', 'two' => '4'],
+ ];
+
+ $object = [
+ (object) ['one' => '1', 'two' => '1'],
+ (object) ['one' => '2', 'two' => '2'],
+ (object) ['one' => '3', 'two' => '3'],
+ (object) ['one' => '4', 'two' => '4'],
+ ];
+
+ return [
+ [
+ 'function' => 'mysql_fetch_array',
+ 'results' => $array
+ ],
+ [
+ 'function' => 'mysql_fetch_assoc',
+ 'results' => $assoc
+ ],
+ [
+ 'function' => 'mysql_fetch_row',
+ 'results' => $numeric
+ ],
+ [
+ 'function' => 'mysql_fetch_object',
+ 'results' => $object,
+ ]
+ ];
+ }
+
+ /**
+ * @param $result
+ */
+ protected function assertResult($result)
+ {
+ $this->assertTrue(
+ is_resource($result) && get_resource_type($result) == 'mysql result'
+ || $result instanceof \mysqli_result,
+ \mysql_error()
+ );
+ }
+
+ protected function getConnection($db = null)
+ {
+ $mysql = \mysql_connect(static::$host, 'root');
+ $this->assertConnection($mysql);
+
+ if ($db !== null) {
+ $this->assertTrue(\mysql_select_db('shim_test'));
+ }
+
+ return $mysql;
+ }
+
+ /**
+ * @param $mysql
+ */
+ protected function assertConnection($mysql)
+ {
+ $this->assertTrue(
+ is_resource($mysql) && get_resource_type($mysql) == 'mysql link'
+ ||
+ $mysql instanceof \mysqli,
+ "Not a valid MySQL connection"
+ );
+ }
}