Implement Result and Connection::query()
[MAILPOET-6142]
This commit is contained in:
@ -25,7 +25,10 @@ class Connection implements ServerInfoAwareConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function query(string $sql): Result {
|
public function query(string $sql): Result {
|
||||||
// TODO: Implement query() method.
|
global $wpdb;
|
||||||
|
$value = $this->runQuery($sql);
|
||||||
|
$result = $wpdb->last_result;
|
||||||
|
return new Result($result, is_int($value) ? $value : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exec(string $sql): int {
|
public function exec(string $sql): int {
|
||||||
|
@ -4,40 +4,69 @@ namespace MailPoet\Doctrine\WPDB;
|
|||||||
|
|
||||||
use MailPoetVendor\Doctrine\DBAL\Driver\Result as ResultInterface;
|
use MailPoetVendor\Doctrine\DBAL\Driver\Result as ResultInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPDB fetches all results from the underlying database driver,
|
||||||
|
* so we need to implement the result methods on in-memory data.
|
||||||
|
*/
|
||||||
class Result implements ResultInterface {
|
class Result implements ResultInterface {
|
||||||
|
/** @var array[] */
|
||||||
|
private array $result = [];
|
||||||
|
private int $rowCount;
|
||||||
|
private int $cursor = 0;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
array $result,
|
||||||
|
int $rowCount
|
||||||
|
) {
|
||||||
|
foreach ($result as $value) {
|
||||||
|
$this->result[] = (array)$value;
|
||||||
|
}
|
||||||
|
$this->rowCount = $rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
public function fetchNumeric() {
|
public function fetchNumeric() {
|
||||||
// TODO: Implement fetchNumeric() method.
|
$value = $this->result[$this->cursor++] ?? null;
|
||||||
|
return $value === null ? false : array_values($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchAssociative() {
|
public function fetchAssociative() {
|
||||||
// TODO: Implement fetchAssociative() method.
|
return $this->result[$this->cursor++] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchOne() {
|
public function fetchOne() {
|
||||||
// TODO: Implement fetchOne() method.
|
$value = $this->result[$this->cursor++] ?? null;
|
||||||
|
return $value === null ? false : reset($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchAllNumeric(): array {
|
public function fetchAllNumeric(): array {
|
||||||
// TODO: Implement fetchAllNumeric() method.
|
$result = [];
|
||||||
|
foreach ($this->result as $value) {
|
||||||
|
$result[] = array_values($value);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchAllAssociative(): array {
|
public function fetchAllAssociative(): array {
|
||||||
// TODO: Implement fetchAllAssociative() method.
|
return $this->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetchFirstColumn(): array {
|
public function fetchFirstColumn(): array {
|
||||||
// TODO: Implement fetchFirstColumn() method.
|
$result = [];
|
||||||
|
foreach ($this->result as $value) {
|
||||||
|
$result[] = reset($value);
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rowCount(): int {
|
public function rowCount(): int {
|
||||||
// TODO: Implement rowCount() method.
|
return $this->rowCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function columnCount(): int {
|
public function columnCount(): int {
|
||||||
// TODO: Implement columnCount() method.
|
return count($this->result[0] ?? []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function free(): void {
|
public function free(): void {
|
||||||
// TODO: Implement free() method.
|
$this->cursor = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\Test\Doctrine\WPDB;
|
namespace MailPoet\Test\Doctrine\WPDB;
|
||||||
|
|
||||||
use MailPoet\Doctrine\WPDB\Connection;
|
use MailPoet\Doctrine\WPDB\Connection;
|
||||||
|
use MailPoet\Doctrine\WPDB\Result;
|
||||||
use MailPoetTest;
|
use MailPoetTest;
|
||||||
use mysqli;
|
use mysqli;
|
||||||
|
|
||||||
@ -24,6 +25,30 @@ class ConnectionTest extends MailPoetTest {
|
|||||||
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testQuery(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
|
||||||
|
// select
|
||||||
|
$result = $connection->query('SELECT 123');
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame('123', $result->fetchOne());
|
||||||
|
|
||||||
|
// insert
|
||||||
|
$result = $connection->query(sprintf("INSERT INTO %s (value) VALUES ('test')", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertFalse($result->fetchOne());
|
||||||
|
|
||||||
|
// update
|
||||||
|
$result = $connection->query(sprintf("UPDATE %s SET value = 'updated' WHERE id = %d", self::TEST_TABLE_NAME, $connection->lastInsertId()));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertFalse($result->fetchOne());
|
||||||
|
|
||||||
|
// delete
|
||||||
|
$result = $connection->query(sprintf("DELETE FROM %s WHERE id = %d", self::TEST_TABLE_NAME, $connection->lastInsertId()));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertFalse($result->fetchOne());
|
||||||
|
}
|
||||||
|
|
||||||
public function testExec(): void {
|
public function testExec(): void {
|
||||||
$connection = new Connection();
|
$connection = new Connection();
|
||||||
|
|
||||||
|
165
mailpoet/tests/integration/Doctrine/WPDB/ResultTest.php
Normal file
165
mailpoet/tests/integration/Doctrine/WPDB/ResultTest.php
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Test\Doctrine\WPDB;
|
||||||
|
|
||||||
|
use MailPoet\Doctrine\WPDB\Connection;
|
||||||
|
use MailPoet\Doctrine\WPDB\Result;
|
||||||
|
use MailPoetTest;
|
||||||
|
|
||||||
|
class ResultTest extends MailPoetTest {
|
||||||
|
private const TEST_TABLE_NAME = 'doctrine_wpdb_result_test';
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->exec(sprintf('DROP TABLE IF EXISTS %s', self::TEST_TABLE_NAME));
|
||||||
|
$connection->exec(sprintf('
|
||||||
|
CREATE TABLE %s (
|
||||||
|
id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
value varchar(255) NOT NULL)
|
||||||
|
', self::TEST_TABLE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInsert(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$result = $connection->query(sprintf("INSERT INTO %s (value) VALUES ('test')", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(1, $result->rowCount());
|
||||||
|
$this->assertSame(0, $result->columnCount());
|
||||||
|
$this->assertSame([], $result->fetchAllAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdate(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('test')", self::TEST_TABLE_NAME));
|
||||||
|
$result = $connection->query(sprintf("UPDATE %s SET value = 'updated' WHERE id = %d", self::TEST_TABLE_NAME, $connection->lastInsertId()));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(1, $result->rowCount());
|
||||||
|
$this->assertSame(0, $result->columnCount());
|
||||||
|
$this->assertSame([], $result->fetchAllAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchNumeric(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(['1', 'aaa'], $result->fetchNumeric());
|
||||||
|
$this->assertSame(['2', 'bbb'], $result->fetchNumeric());
|
||||||
|
$this->assertSame(['3', 'ccc'], $result->fetchNumeric());
|
||||||
|
$this->assertFalse($result->fetchNumeric());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAssociative(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(['id' => '1', 'value' => 'aaa'], $result->fetchAssociative());
|
||||||
|
$this->assertSame(['id' => '2', 'value' => 'bbb'], $result->fetchAssociative());
|
||||||
|
$this->assertSame(['id' => '3', 'value' => 'ccc'], $result->fetchAssociative());
|
||||||
|
$this->assertFalse($result->fetchAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchOne(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
$this->assertSame('2', $result->fetchOne());
|
||||||
|
$this->assertSame('3', $result->fetchOne());
|
||||||
|
$this->assertFalse($result->fetchOne());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAllNumeric(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame([['1', 'aaa'], ['2', 'bbb'], ['3', 'ccc']], $result->fetchAllNumeric());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAllAssociative(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame([
|
||||||
|
['id' => '1', 'value' => 'aaa'],
|
||||||
|
['id' => '2', 'value' => 'bbb'],
|
||||||
|
['id' => '3', 'value' => 'ccc'],
|
||||||
|
], $result->fetchAllAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchFirstColumn(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(['1', '2', '3'], $result->fetchFirstColumn());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRowCount(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(3, $result->rowCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testColumnCount(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame(2, $result->columnCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFree(): void {
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('aaa')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('bbb')", self::TEST_TABLE_NAME));
|
||||||
|
$connection->query(sprintf("INSERT INTO %s (value) VALUES ('ccc')", self::TEST_TABLE_NAME));
|
||||||
|
|
||||||
|
$result = $connection->query(sprintf("SELECT * FROM %s", self::TEST_TABLE_NAME));
|
||||||
|
$this->assertInstanceOf(Result::class, $result);
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
$this->assertSame('2', $result->fetchOne());
|
||||||
|
$this->assertSame('3', $result->fetchOne());
|
||||||
|
$this->assertFalse($result->fetchOne());
|
||||||
|
|
||||||
|
$result->free();
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function _after() {
|
||||||
|
parent::_after();
|
||||||
|
$connection = new Connection();
|
||||||
|
$connection->exec(sprintf('DROP TABLE IF EXISTS %s', self::TEST_TABLE_NAME));
|
||||||
|
}
|
||||||
|
}
|
107
mailpoet/tests/unit/Doctrine/WPDB/ResultTest.php
Normal file
107
mailpoet/tests/unit/Doctrine/WPDB/ResultTest.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Doctrine\WPDB;
|
||||||
|
|
||||||
|
use MailPoetUnitTest;
|
||||||
|
|
||||||
|
class ResultTest extends MailPoetUnitTest {
|
||||||
|
/** @var object[] */
|
||||||
|
private array $data;
|
||||||
|
|
||||||
|
public function _before() {
|
||||||
|
parent::_before();
|
||||||
|
$this->data = [
|
||||||
|
(object)['id' => '1', 'value' => 'aaa'],
|
||||||
|
(object)['id' => '2', 'value' => 'bbb'],
|
||||||
|
(object)['id' => '3', 'value' => 'ccc'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchNumeric(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame(['1', 'aaa'], $result->fetchNumeric());
|
||||||
|
$this->assertSame(['2', 'bbb'], $result->fetchNumeric());
|
||||||
|
$this->assertSame(['3', 'ccc'], $result->fetchNumeric());
|
||||||
|
$this->assertSame(false, $result->fetchNumeric());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame(false, $result->fetchNumeric());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAssociative(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame(['id' => '1', 'value' => 'aaa'], $result->fetchAssociative());
|
||||||
|
$this->assertSame(['id' => '2', 'value' => 'bbb'], $result->fetchAssociative());
|
||||||
|
$this->assertSame(['id' => '3', 'value' => 'ccc'], $result->fetchAssociative());
|
||||||
|
$this->assertSame(false, $result->fetchAssociative());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame(false, $result->fetchAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchOne(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
$this->assertSame('2', $result->fetchOne());
|
||||||
|
$this->assertSame('3', $result->fetchOne());
|
||||||
|
$this->assertSame(false, $result->fetchOne());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame(false, $result->fetchOne());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAllNumeric(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame([['1', 'aaa'], ['2', 'bbb'], ['3', 'ccc']], $result->fetchAllNumeric());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame([], $result->fetchAllNumeric());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchAllAssociative(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame([
|
||||||
|
['id' => '1', 'value' => 'aaa'],
|
||||||
|
['id' => '2', 'value' => 'bbb'],
|
||||||
|
['id' => '3', 'value' => 'ccc'],
|
||||||
|
], $result->fetchAllAssociative());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame([], $result->fetchAllAssociative());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFetchFirstColumn(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame(['1', '2', '3'], $result->fetchFirstColumn());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame([], $result->fetchFirstColumn());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRowCount(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame(2, $result->rowCount());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame(0, $result->rowCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testColumnCount(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame(2, $result->columnCount());
|
||||||
|
|
||||||
|
$result = new Result([], 0);
|
||||||
|
$this->assertSame(0, $result->columnCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFree(): void {
|
||||||
|
$result = new Result($this->data, 2);
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
$this->assertSame('2', $result->fetchOne());
|
||||||
|
$this->assertSame('3', $result->fetchOne());
|
||||||
|
$this->assertSame(false, $result->fetchOne());
|
||||||
|
|
||||||
|
$result->free();
|
||||||
|
$this->assertSame('1', $result->fetchOne());
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user