Skip to content

Commit

Permalink
Upgrade to Doctrine DBAL 3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
iquito committed Nov 17, 2020
1 parent cc61557 commit a4de370
Show file tree
Hide file tree
Showing 21 changed files with 477 additions and 348 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
"php": ">=7.4",
"ext-pdo": "*",
"squirrelphp/debug": "^0.5",
"doctrine/dbal": "^2.5"
"doctrine/dbal": "^3.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.3",
"captainhook/plugin-composer": "^5.0",
"phpunit/phpunit": "^9.0",
"mockery/mockery": "^1.0"
},
"suggest": {
Expand Down Expand Up @@ -59,7 +60,7 @@
"psalm_base": "vendor/bin/psalm --set-baseline=psalm-baseline.xml",
"phpunit": "vendor/bin/phpunit --colors=always",
"phpunit_clover": "vendor/bin/phpunit --coverage-text --coverage-clover build/logs/clover.xml",
"codecoverage": "vendor/bin/phpunit --coverage-html tests/_reports",
"coverage": "vendor/bin/phpunit --coverage-html tests/_reports",
"phpcs": "vendor/bin/phpcs --standard=ruleset.xml --extensions=php --cache=.phpcs-cache --colors src tests",
"phpcsfix": "vendor/bin/phpcbf --standard=ruleset.xml --extensions=php --cache=.phpcs-cache src tests",
"binupdate": "@composer bin all update --ansi",
Expand Down
64 changes: 64 additions & 0 deletions docker/compose-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
version: "3.7"
services:
squirrel_queries_coverage:
image: thecodingmachine/php:7.4-v3-cli
container_name: squirrel_queries_coverage
tty: true
working_dir: /usr/src/app
# --path-coverage could be added later, it is much too slow currently and only supported by xdebug
command: [ "vendor/bin/phpunit", "--colors=always", "--stop-on-defect", "--coverage-html", "tests/_reports"]
volumes:
- ./src:/usr/src/app/src
- ./tests:/usr/src/app/tests
- ./composer.json:/usr/src/app/composer.json
- ./phpunit.xml.dist:/usr/src/app/phpunit.xml.dist
- ./vendor-bin:/usr/src/app/vendor-bin
environment:
# We currently use PCOV because it is at least 8x faster
# - 3 seconds compared to 23 seconds (or 5 minutes with path coverage enabled)
PHP_EXTENSION_XDEBUG: 1
#PHP_EXTENSION_PCOV: 1
PHP_EXTENSION_APCU: 0
PHP_EXTENSION_REDIS: 0
PHP_EXTENSION_SQLITE3: 1
PHP_EXTENSION_PDO_MYSQL: 1
PHP_EXTENSION_PDO_PGSQL: 1
PHP_EXTENSION_PDO_SQLITE: 1
PHP_INI_MEMORY_LIMIT: 1g
PHP_INI_ERROR_REPORTING: E_ALL
SQUIRREL_TEST_SQLITE: 'sqlite:///:memory:'
SQUIRREL_TEST_POSTGRES: 'postgres://user:password@squirrel_queries_postgres/postgres?charset=UTF-8'
SQUIRREL_TEST_MYSQL: 'mysql://user:password@squirrel_queries_mysql/shop'
SQUIRREL_TEST_MARIADB: 'mysql://user:password@squirrel_queries_mariadb/shop'
STARTUP_COMMAND_1: composer update --no-scripts --quiet
STARTUP_COMMAND_2: rm -rf /usr/src/app/tests/_reports/*
depends_on:
- squirrel_queries_postgres
- squirrel_queries_mysql
- squirrel_queries_mariadb

squirrel_queries_postgres:
image: postgres:latest
container_name: squirrel_queries_postgres
environment:
POSTGRES_USER: 'user'
POSTGRES_PASSWORD: 'password'

squirrel_queries_mysql:
image: mysql/mysql-server:latest
container_name: squirrel_queries_mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: 'whatever'
MYSQL_DATABASE: 'shop'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'

squirrel_queries_mariadb:
image: mariadb:latest
container_name: squirrel_queries_mariadb
environment:
MYSQL_ROOT_PASSWORD: 'whatever'
MYSQL_DATABASE: 'shop'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
5 changes: 2 additions & 3 deletions docker/compose-test.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: "3.7"
services:
squirrel_queries_74:
squirrel_queries_test:
image: thecodingmachine/php:7.4-v3-cli
container_name: squirrel_queries_74
container_name: squirrel_queries_test
tty: true
working_dir: /usr/src/app
command: ["vendor/bin/phpunit", "--colors=always", "--filter", "Integration"]
Expand All @@ -26,7 +26,6 @@ services:
SQUIRREL_TEST_MYSQL: 'mysql://user:password@squirrel_queries_mysql/shop'
SQUIRREL_TEST_MARIADB: 'mysql://user:password@squirrel_queries_mariadb/shop'
STARTUP_COMMAND_1: composer update --no-scripts --quiet
STARTUP_COMMAND_2: composer bin all update --quiet
depends_on:
- squirrel_queries_postgres
- squirrel_queries_mysql
Expand Down
12 changes: 12 additions & 0 deletions docker/coverage
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Get directory of this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

# Remove all running docker containers
docker-compose -f "$DIR/compose-coverage.yml" --project-directory "$DIR/.." down -v --remove-orphans

# Test SQLite and real live tests with PostgreSQL and MySQL
docker-compose -f "$DIR/compose-coverage.yml" --project-directory "$DIR/.." up --build --force-recreate --renew-anon-volumes squirrel_queries_coverage

# Remove all running docker containers
docker-compose -f "$DIR/compose-coverage.yml" --project-directory "$DIR/.." down -v
6 changes: 2 additions & 4 deletions docker/test-pull → docker/pull
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
# Get directory of this script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

# Remove all running docker containers
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." down -v --remove-orphans

# Pull new docker images in case there were updates
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." pull
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." pull
docker-compose -f "$DIR/compose-coverage.yml" --project-directory "$DIR/.." pull
2 changes: 1 addition & 1 deletion docker/test
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." down -v --remove-orphans

# Test SQLite and real live tests with PostgreSQL and MySQL
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." up --build --force-recreate --renew-anon-volumes squirrel_queries_74
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." up --build --force-recreate --renew-anon-volumes squirrel_queries_test

# Remove all running docker containers
docker-compose -f "$DIR/compose-test.yml" --project-directory "$DIR/.." down -v
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ parameters:
count: 1
path: src/Builder/SelectEntries.php

-
message: "#^Cannot access offset 'v' on array\\<string, mixed\\>\\|false\\.$#"
count: 1
path: src/Doctrine/DBSQLiteImplementation.php

36 changes: 14 additions & 22 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/9.1/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
>
<testsuites>
<testsuite name="Unit Tests">
<directory>tests</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory suffix=".php">src</directory>
<exclude>
<directory>src/TestHelpers</directory>
</exclude>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" backupGlobals="false" colors="true" bootstrap="vendor/autoload.php">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
<exclude>
<directory>src/TestHelpers</directory>
</exclude>
</coverage>
<testsuites>
<testsuite name="Unit Tests">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
11 changes: 8 additions & 3 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.14.2@3538fe1955d47f6ee926c0769d71af6db08aa488">
<files psalm-version="3.18.2@19aa905f7c3c7350569999a93c40ae91ae4e1626">
<file src="src/Builder/FlattenedFieldsWithTypeTrait.php">
<InvalidReturnType occurrences="4">
<code>int[]</code>
<code>bool[]</code>
<code>float[]</code>
<code>int[]</code>
<code>string[]</code>
<code>bool[]</code>
</InvalidReturnType>
</file>
<file src="src/Builder/SelectIteratorTrait.php">
Expand All @@ -18,4 +18,9 @@
<code>$lowerLayer</code>
</MissingConstructor>
</file>
<file src="src/Doctrine/DBAbstractImplementation.php">
<PossiblyNullArgument occurrences="1">
<code>$select['offset'] ?? null</code>
</PossiblyNullArgument>
</file>
</files>
25 changes: 12 additions & 13 deletions src/Doctrine/DBAbstractImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace Squirrel\Queries\Doctrine;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\FetchMode;
use Squirrel\Debug\Debug;
use Squirrel\Queries\DBInterface;
use Squirrel\Queries\DBRawInterface;
Expand Down Expand Up @@ -76,10 +75,10 @@ public function select($query, array $vars = []): DBSelectQueryInterface

// Prepare and execute query
$statement = $this->connection->prepare($query);
$statement->execute($vars);
$statementResult = $statement->execute($vars);

// Return select query object with PDO statement
return new DBSelectQuery($statement);
return new DBSelectQuery($statementResult);
}

public function fetch(DBSelectQueryInterface $selectQuery): ?array
Expand All @@ -94,7 +93,7 @@ public function fetch(DBSelectQueryInterface $selectQuery): ?array
}

// Get the result - can be an array of the entry, or false if it is empty
$result = $selectQuery->getStatement()->fetch(FetchMode::ASSOCIATIVE);
$result = $selectQuery->getStatement()->fetchAssociative();

// Return one result as an array
return ($result === false ? null : $result);
Expand All @@ -112,7 +111,7 @@ public function clear(DBSelectQueryInterface $selectQuery): void
}

// Close the result set
$selectQuery->getStatement()->closeCursor();
$selectQuery->getStatement()->free();
}

public function fetchOne($query, array $vars = []): ?array
Expand All @@ -135,11 +134,11 @@ public function fetchAll($query, array $vars = []): array

// Prepare and execute query
$statement = $this->connection->prepare($query);
$statement->execute($vars);
$statementResult = $statement->execute($vars);

// Get result and close result set
$result = $statement->fetchAll(FetchMode::ASSOCIATIVE);
$statement->closeCursor();
$result = $statementResult->fetchAllAssociative();
$statementResult->free();

// Return query result
return $result;
Expand Down Expand Up @@ -188,8 +187,8 @@ public function insert(string $tableName, array $row = [], string $autoIncrement
($columnValue instanceof LargeObject) ? \PDO::PARAM_LOB : \PDO::PARAM_STR,
);
}
$statement->execute();
$statement->closeCursor();
$statementResult = $statement->execute();
$statementResult->free();

// No autoincrement index - no insert ID return value needed
if (\strlen($autoIncrementIndex) === 0) {
Expand Down Expand Up @@ -262,13 +261,13 @@ public function change(string $query, array $vars = []): int
($columnValue instanceof LargeObject) ? \PDO::PARAM_LOB : \PDO::PARAM_STR,
);
}
$statement->execute();
$statementResult = $statement->execute();

// Get affected rows
$result = $statement->rowCount();
$result = $statementResult->rowCount();

// Close query
$statement->closeCursor();
$statementResult->free();

// Return affected rows
return $result;
Expand Down
5 changes: 0 additions & 5 deletions src/Doctrine/DBErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,6 @@ protected function attemptReconnect(array $connectionRetries): ?array
// Close connection and establish a new connection
$connection->close();
$connection->connect();

// If we still do not have a connection we need to try again
if ($connection->ping() === false) {
return $this->attemptReconnect($connectionRetries);
}
} catch (ConnectionException $e) { // Connection could not be established - try again
return $this->attemptReconnect($connectionRetries);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Doctrine/DBMySQLImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function insertOrUpdate(string $tableName, array $row = [], array $indexC
);
}

$statement->execute();
$statement->closeCursor();
$statementResult = $statement->execute();
$statementResult->free();
}
}
4 changes: 2 additions & 2 deletions src/Doctrine/DBPostgreSQLImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public function insertOrUpdate(string $tableName, array $row = [], array $indexC
);
}

$statement->execute();
$statement->closeCursor();
$statementResult = $statement->execute();
$statementResult->free();
}

protected function generateUpsertSQLAndParameters(
Expand Down
19 changes: 18 additions & 1 deletion src/Doctrine/DBSQLiteImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

namespace Squirrel\Queries\Doctrine;

use Squirrel\Debug\Debug;
use Squirrel\Queries\DBInterface;
use Squirrel\Queries\Exception\DBInvalidOptionException;

/**
* DB SQLite implementation using Doctrine DBAL with custom upsert functionality
*
Expand All @@ -23,7 +27,20 @@ public function insertOrUpdate(
if ($this->sqliteVersion === null) {
$connection = $this->getConnection();

$this->sqliteVersion = \floatval($connection->query('select sqlite_version() AS "v"')->fetch()['v']);
$statement = $connection->prepare('select sqlite_version() AS "v"');
$statementResult = $statement->execute();
$result = $statementResult->fetchAssociative();
$statementResult->free();

if (!isset($result['v'])) {
throw Debug::createException(
DBInvalidOptionException::class,
DBInterface::class,
'SQLite version could not be retrieved',
);
}

$this->sqliteVersion = \floatval($result['v']);
}

// SQLite below version 3.24 does not offer native upsert, so emulate it
Expand Down
8 changes: 4 additions & 4 deletions src/Doctrine/DBSelectQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

namespace Squirrel\Queries\Doctrine;

use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Result;
use Squirrel\Queries\DBSelectQueryInterface;

class DBSelectQuery implements DBSelectQueryInterface
{
private ResultStatement $statement;
private Result $statement;

public function __construct(ResultStatement $statement)
public function __construct(Result $statement)
{
$this->statement = $statement;
}

public function getStatement(): ResultStatement
public function getStatement(): Result
{
return $this->statement;
}
Expand Down
Loading

0 comments on commit a4de370

Please sign in to comment.