diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4799c899..a31867d3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,6 @@ jobs: strategy: matrix: php: - - 8.0 - 8.1 - 8.2 - 8.3 diff --git a/composer.json b/composer.json index aeb5a8df..8904d7b6 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "type": "library", "license": "Apache-2.0", "require": { - "php": ">=8.0", + "php": ">=8.1", "aura/sqlquery": "^2.6", "doctrine/cache": "^1.6", "symfony/property-access": "^6.0 || ^7.0" diff --git a/src/Ting/Driver/Pgsql/Driver.php b/src/Ting/Driver/Pgsql/Driver.php index eece0c2a..bea9cc31 100755 --- a/src/Ting/Driver/Pgsql/Driver.php +++ b/src/Ting/Driver/Pgsql/Driver.php @@ -59,7 +59,7 @@ class Driver implements DriverInterface protected $currentTimezone = null; /** - * @var resource|null + * @var \PgSql\Connection|null */ protected $connection = null; @@ -79,7 +79,7 @@ class Driver implements DriverInterface protected $objectHash = ''; /** - * @var resource|null + * @var resource|\PgSql\Result|null */ protected $result = null; diff --git a/tests/units/Ting/Driver/Pgsql/Driver.php b/tests/units/Ting/Driver/Pgsql/Driver.php deleted file mode 100644 index e1174c31..00000000 --- a/tests/units/Ting/Driver/Pgsql/Driver.php +++ /dev/null @@ -1,780 +0,0 @@ - '127.0.0.1', 'user' => 'app_read', 'password' => 'pzefgdfg', 'port' => 3306]; - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->string($driver->getConnectionKey($connectionConfig, 'myDatabase')) - ->isIdenticalTo($driver->getConnectionKey($connectionConfig, 'myDatabase')) - ->isIdenticalTo($driver->getConnectionKey($connectionConfig, 'myDatabase')) - ; - } - - public function testShouldImplementDriverInterface() - { - $this - ->object(new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\DriverInterface::class); - } - - public function testConnectShouldReturnSelf() - { - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->object($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->isIdenticalTo($driver); - } - - public function testCloseShouldReturnSelf() - { - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->object($driver->close()) - ->isIdenticalTo($driver); - } - - public function testIfNotConnectedCallbackAfterClosedConnection() - { - $called = false; - - PGMock::override('pg_connect', true); - PGMock::override('pg_close', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('database.test')) - ->then($driver->close()) - ->then($driver->ifIsNotConnected(function () use (&$called): void { - $called = true; - })) - ->boolean($called) - ->isTrue(); - } - - public function testSetCharset() - { - $mockDriver = new \mock\Fake\Pgsql(); - PGMock::override('pg_connect', true); - PGMock::override('pg_close', true); - PGMock::override('pg_set_client_encoding', function ($connection, $charset) use (&$outerCharset): void { - $outerCharset = $charset; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver($mockDriver)) - ->then($driver->setCharset('utf8')) - ->variable($outerCharset) - ->isIdenticalTo('utf8'); - } - - public function testSetCharsetCallingTwiceShouldCallMysqliSetCharsetOnce() - { - $mockDriver = new \mock\Fake\Pgsql(); - PGMock::override('pg_connect', true); - $called = 0; - PGMock::override('pg_set_client_encoding', function () use (&$called): void { - $called++; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver($mockDriver)) - ->then($driver->setCharset('utf8')) - ->then($driver->setCharset('utf8')) - ->variable($called) - ->isIdenticalTo(1); - - } - - public function testSetCharsetWithInvalidCharsetShouldThrowAnException() - { - $mockDriver = new \mock\Fake\Pgsql(); - PGMock::override('pg_set_client_encoding', -1); - PGMock::override('pg_last_error', 'ERROR: invalid value for parameter "client_encoding": "utf8x"'); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver($mockDriver)) - ->exception(function () use ($driver): void { - $driver->setCharset('BadCharset'); - }) - ->hasMessage( - 'Can\'t set charset BadCharset (ERROR: invalid value for parameter "client_encoding": "utf8x")' - ); - } - - public function testSetDatabaseShouldCompleteGeneratedDsnByConnect() - { - PGMock::override('pg_connect', function ($dsn) use (&$outerDsn): void { - $outerDsn = $dsn; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('database.test')) - ->string($outerDsn) - ->isIdenticalTo( - 'host=hostname.test user=user.test password=password.test port=1234 dbname=database.test' - ); - } - - public function testSetDatabaseWhenWrongAuthOrPortShouldRaiseDriverException() - { - PGMock::override('pg_connect', false); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->exception(function () use ($driver): void { - $driver->setDatabase('bouh'); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\Exception::class); - } - - public function testsetDatabaseWithDatabaseAlreadySetShouldDoNothing() - { - $outerCount = 0; - PGMock::override('pg_connect', function ($dsn) use (&$outerCount) { - $outerCount++; - return true; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('bouh')) - ->then($driver->setDatabase('bouh')) - ->integer($outerCount) - ->isIdenticalTo(1); - } - - public function testsetDatabaseShouldReturnSelf() - { - PGMock::override('pg_connect', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->object($driver->setDatabase('bouh')) - ->isIdenticalTo($driver); - } - - public function testIfNotConnectedShouldCallCallback() - { - PGMock::override('pg_connect', false); - $called = false; - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->ifIsNotConnected(function () use (&$called): void { - $called = true; - })) - ->boolean($called) - ->isTrue(); - } - - public function testIfIsErrorShouldCallCallable() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_last_error', 'unknown error'); - - $called = false; - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('database.test')) - ->then($driver->ifIsError(function () use (&$called): void { - $called = true; - })) - ->boolean($called) - ->isTrue(); - } - - public function testPrepareShouldRaiseQueryException() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query', true); - PGMock::override('pg_prepare', false); - PGMock::override('pg_last_error', 'unknown error'); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('database.test')) - ->exception(function () use ($driver): void { - $driver->prepare( - 'SELECT 1 FROM bouh WHERE first = :first AND second = :second' - ); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\QueryException::class); - } - - public function testPrepareShouldNotTransformEscapedColon() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query', true); - PGMock::override('pg_prepare', function ($resource, $statementName, $sql) use (&$outerSql): void { - $outerSql = $sql; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->prepare( - 'SELECT * FROM T_BOUH_BOO WHERE name = "\:bim"' - )) - ->string($outerSql) - ->isIdenticalTo('SELECT * FROM T_BOUH_BOO WHERE name = ":bim"'); - } - - public function testPrepareShouldHandleMultipleNamedPatternWithSameName() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query', true); - PGMock::override('pg_prepare', function ($resource, $statementName, $sql) use (&$outerSql): void { - $outerSql = $sql; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->prepare( - 'SELECT * FROM T_BOUH_BOO WHERE name = ":name" OR firstname = ":name" OR lastname = ":lastname"' - )) - ->string($outerSql) - ->isIdenticalTo('SELECT * FROM T_BOUH_BOO WHERE name = "$1" OR firstname = "$1" OR lastname = "$2"'); - } - - public function testEscapeFieldShouldReturnEscapedField() - { - PGMock::override('pg_connect', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->string($driver->escapeField('Bouh')) - ->isIdenticalTo('"Bouh"') - ; - } - - public function testStartTransactionShouldExecuteQueryBegin() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->startTransaction()) - ->string($outerQuery) - ->isIdenticalTo('BEGIN'); - } - - public function testStartTransactionShouldRaiseException() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->startTransaction()) - ->exception(function () use ($driver): void { - $driver->startTransaction(); - }) - ->hasMessage('Cannot start another transaction'); - - } - - public function testCommitShouldExecuteQueryCommit() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->startTransaction()) - ->then($driver->commit()) - ->string($outerQuery) - ->isIdenticalTo('COMMIT'); - } - - public function testCommitShouldRaiseException() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->commit(); - }) - ->hasMessage('Cannot commit no transaction'); - - } - - public function testRollbackShouldExecuteQueryRollback() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->startTransaction()) - ->then($driver->rollback()) - ->string($outerQuery) - ->isIdenticalTo('ROLLBACK'); - } - - public function testRollbackShouldRaiseException() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->rollback(); - }) - ->hasMessage('Cannot rollback no transaction'); - - } - - public function testGetAffectedRowsWithoutResultShouldReturn0() - { - PGMock::override('pg_affected_rows', 12); - PGMock::override('pg_affected_rows', 12); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->integer($driver->getAffectedRows()) - ->isIdenticalTo(0) - ; - } - - public function testgetInsertedIdShouldReturnInsertedId() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - PGMock::override('pg_fetch_row', [8]); - - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->integer($driver->getInsertedId()) - ->isIdenticalTo(8) - ->string($outerQuery) - ->isIdenticalTo('SELECT lastval()') - ; - } - - public function testgetInsertedIdForSequenceShouldReturnInsertedIdForSequence() - { - PGMock::override('pg_query', function ($connection, $query) use (&$outerQuery): void { - $outerQuery = $query; - }); - - PGMock::override('pg_fetch_row', [4]); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->integer($driver->getInsertedIdForSequence('sequenceName')) - ->isIdenticalTo(4) - ->string($outerQuery) - ->isIdenticalTo("SELECT currval('sequenceName')") - ; - } - - public function testgetInsertedIdForSequenceWithWrongSequenceShouldThrowAnException() - { - PGMock::override('pg_query', false); - PGMock::override('pg_last_error', 'A PGSQL error'); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->getInsertedIdForSequence('sequenceName'); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\QueryException::class) - ->hasMessage("A PGSQL error (Query: SELECT currval('sequenceName'))"); - ; - } - - public function testExecuteShouldCallPGQueryParams() - { - $count = 0; - $outerSql = ''; - $outerValues = ''; - PGMock::override('pg_query_params', function ( - $connection, - $sql, - $values - ) use ( - &$count, - &$outerSql, - &$outerValues - ): void { - $count++; - $outerSql = $sql; - $outerValues = $values; - }); - PGMock::override('pg_result_status', \PGSQL_TUPLES_OK); - PGMock::override('pg_fetch_assoc', null); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->execute('SELECT 1 FROM "myTable" WHERE id = :id', ['id' => 12])) - ->array($outerValues) - ->isIdenticalTo([0 => 12]) - ->string($outerSql) - ->isIdenticalTo('SELECT 1 FROM "myTable" WHERE id = $1') - ->integer($count) - ->isIdenticalTo(1) - ->then($driver->execute( - 'INSERT INTO "myTable" (date_field) VALUES (:date)', - ['date' => '2014-12-31 23:59:59'] - )) - ->array($outerValues) - ->isIdenticalTo([0 => '2014-12-31 23:59:59']) - ->string($outerSql) - ->isIdenticalTo('INSERT INTO "myTable" (date_field) VALUES ($1)') - ->integer($count) - ->isIdenticalTo(2) - ; - } - - public function testExecuteWithoutParametersShouldCallPGQuery() - { - $pgQueryCalled = false; - PGMock::override('pg_query', function () use (&$pgQueryCalled): void { - $pgQueryCalled = true; - }); - - PGMock::override('pg_result_status', \PGSQL_TUPLES_OK); - PGMock::override('pg_fetch_assoc', null); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->execute('SELECT 1 FROM "myTable"')) - ->boolean($pgQueryCalled) - ->isTrue(); - ; - } - - public function testExecuteShouldCallSetOnCollection() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query_params', true); - PGMock::override('pg_fetch_array', 'data'); - PGMock::override('pg_result_seek', true); - PGMock::override('pg_num_fields', 1); - PGMock::override('pg_field_table', 'myTable'); - PGMock::override('pg_field_name', '1'); - - $mockCollection = new \mock\CCMBenchmark\Ting\Repository\Collection(); - $this->calling($mockCollection)->set = true; - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->execute('SELECT 1 FROM myTable WHERE id = :id', ['id' => 12], $mockCollection)) - ->mock($mockCollection) - ->call('set')->once(); - ; - } - - public function testExecuteShouldReturnArray() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query_params', true); - PGMock::override('pg_fetch_assoc', ['Bouh' => 'Hop']); - PGMock::override('pg_result_status', \PGSQL_TUPLES_OK); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->array($driver->execute('SELECT 1 FROM myTable WHERE id = :id', ['id' => 12])) - ->isIdenticalTo(['Bouh' => 'Hop']); - } - - public function testExecuteShouldOnlyReplaceParameters() - { - $outerSql = true; - $outerValues = []; - PGMock::override('pg_connect', true); - PGMock::override('pg_query_params', function ($connection, $sql, $values) use (&$outerSql, &$outerValues): void { - $outerSql = $sql; - $outerValues = $values; - }); - PGMock::override('pg_fetch_assoc', ['Bouh' => 'Hop']); - PGMock::override('pg_result_status', \PGSQL_TUPLES_OK); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->execute( - "SELECT 'Bouh:Ting', ' ::Ting', ADDTIME('23:59:59', '1:1:1') ' - . ' FROM Bouh WHERE id = :id AND login = :login", - ['id' => 3, 'login' => 'Sylvain'] - )) - ->string($outerSql) - ->isIdenticalTo("SELECT 'Bouh:Ting', ' ::Ting', ADDTIME('23:59:59', '1:1:1') ' - . ' FROM Bouh WHERE id = $1 AND login = $2") - ->array($outerValues) - ->isIdenticalTo([3, 'Sylvain']); - } - - public function testExecuteShouldRaiseExceptionWhenErrorHappensWithQuery() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query_params', false); - PGMock::override('pg_fetch_array', 'data'); - PGMock::override('pg_result_seek', true); - PGMock::override('pg_field_table', 'myTable'); - PGMock::override('pg_last_error', 'Unknown Error'); - - $mockCollection = new \mock\CCMBenchmark\Ting\Repository\Collection(); - $this->calling($mockCollection)->set = true; - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->execute('SELECT 1 FROM myTable WHERE id = :id', ['id' => 12]); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\QueryException::class) - ->hasMessage('Unknown Error (Query: SELECT 1 FROM myTable WHERE id = $1)') - - ; - } - - public function testExecuteShouldLogQuery() - { - PGMock::override('pg_query_params', true); - PGMock::override('pg_fetch_array', 'data'); - PGMock::override('pg_result_seek', true); - PGMock::override('pg_field_table', 'myTable'); - PGMock::override('pg_result_status', \PGSQL_TUPLES_OK); - PGMock::override('pg_fetch_assoc', null); - - $mockLogger = new \mock\tests\fixtures\FakeLogger\FakeDriverLogger(); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->and($driver->setLogger($mockLogger)) - ->then($driver->execute('SELECT 1 FROM myTable WHERE id = :id', ['id' => 12])) - ->mock($mockLogger) - ->call('startQuery') - ->once() - ->call('stopQuery') - ->once() - ; - } - - public function testPrepareShouldLogQuery() - { - PGMock::override('pg_prepare', true); - PGMock::override('pg_query', true); - PGMock::override('pg_fetch_array', 'data'); - PGMock::override('pg_result_seek', true); - PGMock::override('pg_field_table', 'myTable'); - - $mockLogger = new \mock\tests\fixtures\FakeLogger\FakeDriverLogger(); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->and($driver->setLogger($mockLogger)) - ->then($driver->prepare('SELECT 1 FROM myTable WHERE id = :id')) - ->mock($mockLogger) - ->call('startPrepare') - ->once() - ->call('stopPrepare') - ->once(); - } - - public function testPrepareCalledTwiceShouldReturnTheSameObject() - { - PGMock::override('pg_prepare', true); - PGMock::override('pg_query', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($statement = $driver->prepare('SELECT 1 FROM myTable WHERE id = :id')) - ->object($driver->prepare('SELECT 1 FROM myTable WHERE id = :id')) - ->isIdenticalTo($statement); - } - - public function testCloseStatementShouldRaiseExceptionOnNonExistentStatement() - { - PGMock::override('pg_prepare', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->closeStatement('NonExistentStatement'); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\Exception::class) - ; - } - - public function testPingShouldCallPingIfConnected() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_ping', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->boolean($driver->ping()) - ->isTrue() - ; - } - - public function testPingShouldCallPingWithCharset() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_ping', true); - PGMock::override('pg_set_client_encoding', function ($connection, $charset) use (&$outerCharset, &$called): void { - $called++; - $outerCharset = $charset; - }); - - $mockDriver = new \mock\Fake\Pgsql(); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver($mockDriver)) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->then($driver->setCharset('UTF8')) - ->boolean($driver->ping()) - ->isTrue() - ->integer($called)->isIdenticalTo(2) - ; - } - - public function testPingShouldCallPingWithTimezone() - { - $called = 0; - $outerArgs = []; - PGMock::override('pg_connect', true); - PGMock::override('pg_ping', true); - PGMock::override('pg_query', function () use (&$called, &$outerArgs) { - $outerArgs[] = func_get_args(); - $called++; - return true; - }); - - $mockDriver = new \mock\Fake\Pgsql(); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver($mockDriver)) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->then($driver->setTimezone('timezone')) - ->boolean($driver->ping()) - ->isTrue() - ->integer($called)->isIdenticalTo(2) - ->array(array_column($outerArgs, 1)) - ->isIdenticalTo(array_fill(0, 2, 'SET timezone = "timezone";')); - ; - } - - public function testPingShouldCallRaiseAnExceptionWhenNotConnected() - { - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->exception(function () use ($driver): void { - $driver->ping(); - }) - ->isInstanceOf(\CCMBenchmark\Ting\Driver\NeverConnectedException::class) - ; - } - - public function testTimezone() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->variable($driver->setTimezone('timezone')) - ->isNull() - ; - } - - public function testDefaultTimezone() - { - PGMock::override('pg_connect', true); - PGMock::override('pg_query', true); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->variable($driver->setTimezone(null)) - ->isNull() - ; - } - - public function testSetTimezoneThenDefaultTimezone() - { - PGMock::override('pg_connect', true); - $outerArgs = []; - PGMock::override('pg_query', function () use (&$outerArgs) { - $outerArgs[] = func_get_args(); - return true; - }); - - $this - ->if($driver = new \CCMBenchmark\Ting\Driver\Pgsql\Driver()) - ->then($driver->connect('hostname.test', 'user.test', 'password.test', 1234)) - ->then($driver->setDatabase('myDatabase')) - ->then($driver->setTimezone('timezone')) - ->variable($outerArgs[0][1]) - ->isIdenticalTo('SET timezone = "timezone";') - ->then($driver->setTimezone(null)) - ->variable($outerArgs[1][1]) - ->isIdenticalTo('SET timezone = DEFAULT;') - ->array($outerArgs) - ->hasSize(2) - ; - } -} diff --git a/tests/units/Ting/Driver/Pgsql/Result.php b/tests/units/Ting/Driver/Pgsql/Result.php deleted file mode 100644 index d3d9bedf..00000000 --- a/tests/units/Ting/Driver/Pgsql/Result.php +++ /dev/null @@ -1,260 +0,0 @@ - match ($index) { - 0 => 't.*', - default => false, - }); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result()) - ->then($result->setConnectionName('connectionName')) - ->then($result->setDatabase('database')) - ->then($result->setResult('result resource')) - ->exception(function () use ($result): void { - $result->setQuery('select t.* from table as t'); - }) - ->hasMessage('Query invalid: usage of asterisk in column definition is forbidden'); - } - - public function testSetQueryShouldNotRaiseExceptionWhenAsteriskIsInACondition() - { - PGMock::override('pg_num_fields', 1); - PGMock::override('pg_field_table', function ($result, $index) { - if ($index === 1) { - return 'table'; - } - return false; - }); - - PGMock::override('pg_field_name', fn ($result, $index) => match ($index) { - 0 => 't.*', - default => false, - }); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result('result resource')) - ->variable( - $result->setQuery( - 'select t.tata CASE WHEN COALESCE(t_avis.note,0) > -5 - THEN (length(t_avis.en_bref) > 200)::integer*100 ELSE 0 END + - COALESCE(t_avis.note,0) as my_note_avis from table as t' - ) - ) - ->isNull(); - } - - public function testSetQueryShouldRaiseExceptionParseColumns() - { - PGMock::override('pg_num_fields', 0); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result()) - ->then($result->setConnectionName('connectionName')) - ->then($result->setDatabase('database')) - ->then($result->setResult('result resource')) - ->exception(function () use ($result): void { - $result->setQuery('selectcolumn from table'); - }) - ->hasMessage('Query invalid: can\'t parse columns'); - } - - public function testSetQueryShouldNotRaiseExceptionWhenThereIsNoFromInTheQuery() - { - PGMock::override('pg_num_fields', 0); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result()) - ->then($result->setConnectionName('connectionName')) - ->then($result->setDatabase('database')) - ->then($result->setResult('result resource')) - ->variable($result->setQuery('select NOW(1)')) - ->isNull(); - } - - public function testIterator() - { - PGMock::override('pg_result_seek', true); - PGMock::override('pg_fetch_array', []); - - $this - ->if($result = new \mock\CCMBenchmark\Ting\Driver\Pgsql\Result()) - ->then($result->setConnectionName('connectionName')) - ->then($result->setDatabase('database')) - ->then($result->setResult('result resource')) - ->then($result->rewind()) - ->mock($result) - ->call('next')->once() - ->then($result->key()) - ->mock($result) - ->call('key')->once() - ->then($result->next()) - ->mock($result) - ->call('next')->twice() - ->then($result->valid()) - ->mock($result) - ->call('valid')->once() - ->then($result->current()) - ->mock($result) - ->call('current')->once(); - } - - public function testIteratorValidShouldReturnFalse() - { - PGMock::override('pg_result_seek', true); - PGMock::override('pg_fetch_array', false); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result()) - ->then($result->setConnectionName('connectionName')) - ->then($result->setDatabase('database')) - ->then($result->setResult('result resource')) - ->then($result->rewind()) - ->then($result->next()) - ->boolean($result->valid()) - ->isFalse(); - } - - public function testGetNumRows() - { - $mockPgsqlResult = new \mock\CCMBenchmark\Ting\Driver\ResultInterface(); - - PGMock::override('pg_num_rows', 10); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result($mockPgsqlResult)) - ->then($result->setResult($mockPgsqlResult)) - ->variable($result->getNumRows()) - ->isEqualTo(10); - } - - public function testSetQueryTakesFullConditionAsColumn() - { - $mockPgsqlResult = new \mock\CCMBenchmark\Ting\Driver\ResultInterface(); - - PGMock::override('pg_fetch_array', [1, 1, 2, 3, 6, 7, 8]); - - PGMock::override('pg_field_table', fn ($result, $index) => 'table'); - - $this - ->if($result = new \CCMBenchmark\Ting\Driver\Pgsql\Result($mockPgsqlResult)) - ->and( - $result->setQuery( - 'SELECT a, - CASE WHEN a = 1 THEN 1 ELSE 0 END, - CASE WHEN a = 1 THEN 2 ELSE 0 END aliased, - CASE WHEN a = 1 THEN 3 ELSE 0 END as aliased2, - CASE WHEN a = 1 THEN 4 ELSE 0 END + 2 as END, - CASE WHEN a = 1 THEN 5 ELSE 0 END + 2 END, - CASE WHEN a = 1 THEN 6 ELSE 0 END + 2 - FROM table' - ) - ) - ->and($result->setResult($mockPgsqlResult)) - ->and($result->next()) - ->then - ->array($result->current()) - ->isEqualTo( - [ - [ - 'name' => 'a', - 'orgName' => 'a', - 'table' => 'table', - 'orgTable' => 'table', - 'schema' => '', - 'value' => 1 - ], - [ - 'name' => 'CASE WHEN a = 1 THEN 1 ELSE 0 END', - 'orgName' => 'CASE WHEN a = 1 THEN 1 ELSE 0 END', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 1 - ], - [ - 'name' => 'aliased', - 'orgName' => 'CASE WHEN a = 1 THEN 2 ELSE 0 END', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 2 - ], - [ - 'name' => 'aliased2', - 'orgName' => 'CASE WHEN a = 1 THEN 3 ELSE 0 END', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 3 - ], - [ - 'name' => 'END', - 'orgName' => 'CASE WHEN a = 1 THEN 4 ELSE 0 END + 2', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 6 - ], - [ - 'name' => 'END', - 'orgName' => 'CASE WHEN a = 1 THEN 5 ELSE 0 END + 2', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 7 - ], - [ - 'name' => 'CASE WHEN a = 1 THEN 6 ELSE 0 END + 2', - 'orgName' => 'CASE WHEN a = 1 THEN 6 ELSE 0 END + 2', - 'table' => '', - 'orgTable' => '', - 'schema' => '', - 'value' => 8 - ] - ] - ) - ; - } -}