Skip to content

Commit cec9833

Browse files
authored
Merge pull request amphp#2 from amphp/master
Merged from upstream
2 parents 6ae0e76 + a88b51f commit cec9833

14 files changed

+176
-44
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ composer.lock
22
vendor
33
mysql-config.php
44
*.pid
5-
test/mysql_db
5+
test/mysql_db

examples/1-connect.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
require 'support/bootstrap.php';
88

9-
\Amp\Loop::run(function() {
9+
Amp\Loop::run(function() {
1010
/* If you want ssl, pass as second argument an array with ssl options (an empty options array is valid too); if null is passed, ssl is not enabled either */
11-
12-
$db = new \Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
11+
$db = new Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
1312

1413
/* use an alternative charset... Default is utf8mb4_general_ci */
1514
$db->setCharset("latin1_general_ci");
@@ -18,4 +17,4 @@
1817

1918
/* we always close the database here so that there is no read/write watcher anymore and Reactor terminates itself */
2019
$db->close();
21-
});
20+
});

examples/2-simple-query.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
require 'support/bootstrap.php';
44

5-
\Amp\Loop::run(function() {
6-
$db = new \Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
5+
Amp\Loop::run(function() {
6+
$db = new Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
77

88
$query = yield $db->query("SELECT 1");
99
list($one) = yield $query->fetchRow();
1010

1111
var_dump($one); // should output string(1) "1"
1212

1313
$db->close();
14-
});
14+
});

examples/3-generic-with-yield.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
require 'support/bootstrap.php';
44

5-
\Amp\Loop::run(function() {
6-
$db = new \Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
5+
Amp\Loop::run(function() {
6+
$db = new Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
77

88
/* Create table and insert a few rows */
99
/* we need to wait until table is finished, so that we can insert. */
1010
yield $db->query("CREATE TABLE IF NOT EXISTS tmp SELECT 1 AS a, 2 AS b");
1111

12+
print "Table successfully created." . PHP_EOL;
13+
1214
$promises = [];
1315
foreach (range(1, 5) as $num) {
14-
$promises[] = $db->query("INSERT INTO tmp (a, b) VALUES ($num, $num * 2)");
16+
$promises[] = $db->prepare("INSERT INTO tmp (a, b) VALUES (?, ? * 2)", [$num, $num]);
1517
}
1618

17-
/* wait until everything is inserted (in case where we wouldn't have to wait, we also could just */
19+
/* wait until everything is inserted */
1820
yield $promises;
1921

20-
print "Insertion successful (if it wasn't, an exception would have been thrown by now)\n";
22+
print "Insertion successful (if it wasn't, an exception would have been thrown by now)" . PHP_EOL;
2123

2224
$db->close();
23-
});
25+
});

examples/4-multi-rows.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
require 'support/bootstrap.php';
44
require 'support/generic-table.php';
55

6-
\Amp\Loop::run(function() {
7-
$db = new \Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
6+
Amp\Loop::run(function() {
7+
$db = new Amp\Mysql\Pool("host=".DB_HOST.";user=".DB_USER.";pass=".DB_PASS.";db=".DB_NAME);
88

99
/* create same table than in 3-generic-with-yield.php */
1010
yield from createGenericTable($db);
1111

12-
/* yeah, we need a lot of yields and assigns here... With PHP 7 we finally can drop a lot of stupid parenthesis! */
13-
$query = (yield $db->query("SELECT a * b FROM tmp"));
14-
while ((list($result) = (yield $query->fetchRow())) !== null) {
12+
/* yeah, we need a lot of yields and assigns here... */
13+
$query = yield $db->query("SELECT a * b FROM tmp");
14+
while ((list($result) = yield $query->fetchRow()) !== null) {
1515
var_dump($result); // outputs each row of the resultset returned by SELECT a * b FROM tmp
1616
}
1717

1818
/* or, maybe, wait until they're all fetched (because you anyway only can continue after having full resultset */
19-
$query = (yield $db->query("SELECT a * b FROM tmp"));
20-
$objs = (yield $query->fetchObjects());
19+
$query = yield $db->query("SELECT a * b FROM tmp");
20+
$objs = yield $query->fetchObjects();
2121
var_dump($objs); // outputs all the rows as objects of the resultset returned by SELECT a * b FROM tmp
2222

2323
yield $db->query("DROP TABLE tmp");
2424

2525
$db->close();
26-
});
26+
});

examples/5-multi-stmts.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
/* multi statements are enabled by default, but generally stored procedures also might return multiple resultsets anyway */
1313
$promise = $db->query("SELECT a + b FROM tmp; SELECT a - b FROM tmp;");
1414

15-
for ($rows = (yield $promise); $rows !== null; $rows = (yield $rows->next())) {
16-
while (($row = (yield $rows->fetch())) !== null) {
15+
for ($rows = yield $promise; $rows !== null; $rows = yield $rows->next()) {
16+
while (($row = yield $rows->fetch()) !== null) {
1717
var_dump($row); // associative array paired with numeric indices
1818
}
1919

@@ -22,4 +22,4 @@
2222
}
2323

2424
$db->close();
25-
});
25+
});

examples/support/bootstrap.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,46 @@
99
@include_once __DIR__ . "/../../mysql-config.php";
1010

1111
if (!defined('DB_HOST') || !defined('DB_USER') || !defined('DB_PASS') || !defined('DB_NAME')) {
12-
throw new \Exception("Must create mysql-config.php in project root directory defining connection constants");
12+
print "We couldn't find a mysql-config.php." . PHP_EOL;
13+
14+
ask_whether_config_should_be_created:
15+
print "Do you want to create a configuration to run the examples? (yes/no): ";
16+
17+
$answer = trim(fgets(STDIN));
18+
19+
if ($answer === "no") {
20+
print "Can't run any examples without valid database credentials." . PHP_EOL;
21+
exit(1);
22+
} else if ($answer === "yes") {
23+
print "Database host: ";
24+
$host = var_export(trim(fgets(STDIN)), true);
25+
26+
print "Database user: ";
27+
$user = var_export(trim(fgets(STDIN)), true);
28+
29+
print "Database password: ";
30+
$pass = var_export(trim(fgets(STDIN)), true);
31+
32+
print "Database name: ";
33+
$name = var_export(trim(fgets(STDIN)), true);
34+
35+
$config = <<<CONFIG
36+
<?php
37+
38+
const DB_HOST = $host;
39+
const DB_USER = $user;
40+
const DB_PASS = $pass;
41+
const DB_NAME = $name;
42+
43+
CONFIG;
44+
45+
file_put_contents(__DIR__ . "/../../mysql-config.php", $config);
46+
require __DIR__ . "/../../mysql-config.php";
47+
48+
print "Successfully created configuration, running example now." . PHP_EOL;
49+
print "You can find the config in " . realpath(__DIR__ . "/../../mysql-config.php") . PHP_EOL;
50+
print str_repeat("-", 80) . PHP_EOL;
51+
} else {
52+
goto ask_whether_config_should_be_created;
53+
}
1354
}

examples/support/generic-table.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?php
22

3-
/* Create table and fill in a few rows for examples; for comments see 003_generic_with_yield.php */
3+
/* Create table and fill in a few rows for examples; for comments see 3-generic-with-yield.php */
44
function createGenericTable(\Amp\Mysql\Pool $db): Generator {
5-
yield $db->query("CREATE TABLE tmp SELECT 1 AS a, 2 AS b");
5+
yield $db->query("CREATE TABLE IF NOT EXISTS tmp SELECT 1 AS a, 2 AS b");
66
$promises = [];
77
foreach (range(1, 5) as $num) {
8-
$promises[] = $db->query("INSERT INTO tmp (a, b) VALUES ($num, $num * 2)");
8+
$promises[] = $db->prepare("INSERT INTO tmp (a, b) VALUES (?, ? * 2)", [$num, $num]);
99
}
1010
return yield $promises;
11-
}
11+
}

lib/Connection.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,10 @@ public function __construct($config, $sslOptions = null) {
4949

5050
public static function parseConnStr($connStr, $sslOptions = null) {
5151
$db = null;
52+
$useCompression = "false";
5253

53-
// well, yes. I *had* to document that behavior change. Future me, feel free to kill me ;-)
5454
foreach (explode(";", $connStr) as $param) {
55-
if (PHP_VERSION_ID < 70000) {
56-
list($$key, $key) = array_reverse(array_map("trim", explode("=", $param, 2)));
57-
} else {
58-
list($key, $$key) = array_map("trim", explode("=", $param, 2));
59-
}
55+
list($key, $$key) = array_map("trim", explode("=", $param, 2) + [1 => null]);
6056
}
6157
if (!isset($host, $user, $pass)) {
6258
throw new \Exception("Required parameters host, user and pass need to be passed in connection string");
@@ -67,6 +63,7 @@ public static function parseConnStr($connStr, $sslOptions = null) {
6763
$config->user = $user;
6864
$config->pass = $pass;
6965
$config->db = $db;
66+
$config->useCompression = $useCompression && $useCompression != "false";
7067

7168
if (is_array($sslOptions)) {
7269
if (isset($sslOptions["key"])) {
@@ -349,4 +346,4 @@ public function prepare($query, $data = null) {
349346
public function __destruct() {
350347
$this->processor->delRef();
351348
}
352-
}
349+
}

lib/ConnectionConfig.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ class ConnectionConfig {
1010
public $user;
1111
public $pass;
1212
public $db = null;
13+
14+
public $useCompression = false;
15+
1316
/* null for no ssl, array with eventual ssl context options (peer_name is automatically set) */
1417
public $ssl = null;
1518

@@ -27,4 +30,4 @@ class ConnectionConfig {
2730
public $collate = "utf8mb4_general_ci";
2831
/* private key to use for sha256_password auth method */
2932
public $key = null;
30-
}
33+
}

lib/Processor.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ public function closeStmt($stmtId) {
334334
if ($this->connectionState === self::READY) {
335335
$this->out[] = null;
336336
$this->sendPacket($payload);
337+
$this->out[] = null; // does not expect a reply - must be reset immediately
337338
}
338339
$this->ready();
339340
});
@@ -367,7 +368,7 @@ private function established() {
367368
// @TODO flags to use?
368369
$this->capabilities |= self::CLIENT_SESSION_TRACK | self::CLIENT_TRANSACTIONS | self::CLIENT_PROTOCOL_41 | self::CLIENT_SECURE_CONNECTION | self::CLIENT_MULTI_RESULTS | self::CLIENT_PS_MULTI_RESULTS | self::CLIENT_MULTI_STATEMENTS | self::CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA;
369370

370-
if (extension_loaded("zlib")) {
371+
if (extension_loaded("zlib") && $this->config->useCompression) {
371372
$this->capabilities |= self::CLIENT_COMPRESS;
372373
}
373374
}
@@ -552,6 +553,7 @@ private function handleQuery($packet) {
552553
$result->updateState(ResultProxy::COLUMNS_FETCHED);
553554
$this->successfulResultsetFetch();
554555
} else {
556+
$this->parseCallback = null;
555557
$this->getDeferred()->resolve($this->getConnInfo());
556558
$this->ready();
557559
}
@@ -985,8 +987,8 @@ private function parseCompression() {
985987
$buf = "";
986988

987989
while (true) {
988-
while (\strlen($buf) < 4) {
989-
$buf .= (yield $inflated);
990+
while (\strlen($buf) < 7) {
991+
$buf .= yield $inflated;
990992
$inflated = "";
991993
}
992994

@@ -998,7 +1000,7 @@ private function parseCompression() {
9981000

9991001
if ($size > 0) {
10001002
while (\strlen($buf) < $size) {
1001-
$buf .= (yield $inflated);
1003+
$buf .= yield $inflated;
10021004
$inflated = "";
10031005
}
10041006

@@ -1026,7 +1028,7 @@ private function parseMysql(): \Generator {
10261028

10271029
do {
10281030
while (\strlen($buf) < 4) {
1029-
$buf .= (yield $parsed);
1031+
$buf .= yield $parsed;
10301032
$parsed = [];
10311033
}
10321034

@@ -1035,7 +1037,7 @@ private function parseMysql(): \Generator {
10351037
$buf = substr($buf, 4);
10361038

10371039
while (\strlen($buf) < ($len & 0xffffff)) {
1038-
$buf .= (yield $parsed);
1040+
$buf .= yield $parsed;
10391041
$parsed = [];
10401042
}
10411043

lib/ResultSet.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ public function fetchRows() {
5050
});
5151
}
5252

53+
public function fetchAssocs() {
54+
return $this->genericFetchAll(function($rows) {
55+
$names = array_column($this->result->columns, "name");
56+
return array_map(function($row) use ($names) {
57+
return array_combine($names, $row);
58+
}, $rows ?: []);
59+
});
60+
}
61+
5362
public function fetchObjects() {
5463
return $this->genericFetchAll(function($rows) {
5564
$names = array_column($this->result->columns, "name");
@@ -94,6 +103,12 @@ public function fetchRow() {
94103
return $this->genericFetch();
95104
}
96105

106+
public function fetchAssoc() {
107+
return $this->genericFetch(function ($row) {
108+
return array_combine(array_column($this->result->columns, "name"), $row);
109+
});
110+
}
111+
97112
public function fetchObject() {
98113
return $this->genericFetch(function ($row) {
99114
return (object) array_combine(array_column($this->result->columns, "name"), $row);

lib/Stmt.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ public function bind($paramId, $data) {
8686
$i = reset($array);
8787
}
8888

89+
if (!is_scalar($data) && !(is_object($data) && method_exists($data, '__toString'))) {
90+
throw new \TypeError("Data must be scalar or object that implements __toString method");
91+
}
92+
8993
do {
9094
$realId = -1;
9195
while (isset($this->named[++$realId]) || $i-- > 0) {

0 commit comments

Comments
 (0)