diff --git a/.github/workflows/coding-style.yml b/.github/workflows/coding-style.yml new file mode 100644 index 000000000..00abb989e --- /dev/null +++ b/.github/workflows/coding-style.yml @@ -0,0 +1,31 @@ +name: Coding Style + +on: [push, pull_request] + +jobs: + nette_cc: + name: Nette Code Checker + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + + - run: composer create-project nette/code-checker temp/code-checker ^3 --no-progress + - run: php temp/code-checker/code-checker --strict-types --no-progress --ignore "tests/*/fixtures" + + + nette_cs: + name: Nette Coding Standard + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + + - run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress --ignore-platform-reqs + - run: php temp/coding-standard/ecs check diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 000000000..f985b0526 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,21 @@ +name: Static Analysis (only informative) + +on: + push: + branches: + - master + +jobs: + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@v2 + with: + php-version: 8.0 + coverage: none + + - run: composer install --no-progress --prefer-dist + - run: composer phpstan -- --no-progress + continue-on-error: true # is only informative diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..b81c281de --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,121 @@ +name: Tests + +on: [push, pull_request] + +env: + php-extensions: mbstring, intl, mysqli, pgsql, sqlsrv-5.9.0preview1, pdo_sqlsrv-5.9.0preview1 + php-tools: "composer:v2, pecl" + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + matrix: + php: ['7.2', '7.3', '7.4', '8.0'] + + fail-fast: false + + name: PHP ${{ matrix.php }} tests + + services: + mysql57: + image: mysql:5.7 + env: + MYSQL_DATABASE: dibi_test + MYSQL_ROOT_PASSWORD: root + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping -ppass" + --health-interval 10s + --health-start-period 10s + --health-timeout 5s + --health-retries 10 + + mysql80: + image: mysql:8.0 + ports: + - 3307:3306 + options: >- + --health-cmd="mysqladmin ping -ppass" + --health-interval=10s + --health-timeout=5s + --health-retries=5 + -e MYSQL_ROOT_PASSWORD=root + -e MYSQL_DATABASE=dibi_test + --entrypoint sh mysql:8 -c "exec docker-entrypoint.sh mysqld --default-authentication-plugin=mysql_native_password" + + postgres96: + image: postgres:9.6 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dibi_test + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + postgres13: + image: postgres:13 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: dibi_test + ports: + - 5433:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + mssql: + image: mcr.microsoft.com/mssql/server:latest + env: + ACCEPT_EULA: Y + SA_PASSWORD: YourStrong!Passw0rd + MSSQL_PID: Developer + ports: + - 1433:1433 + options: >- + --name=mssql + --health-cmd "/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'SELECT 1'" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - uses: actions/checkout@v2 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ${{ env.php-extensions }} + tools: ${{ env.php-tools }} + coverage: none + + - name: Create databases.ini + run: cp ./tests/databases.github.ini ./tests/databases.ini + + - name: Create MS SQL Database + run: docker exec -i mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'YourStrong!Passw0rd' -Q 'CREATE DATABASE dibi_test' + + - run: composer install --no-progress --prefer-dist + - run: vendor/bin/tester -p phpdbg tests -s -C --coverage ./coverage.xml --coverage-src ./src + - if: failure() + uses: actions/upload-artifact@v2 + with: + name: output + path: tests/**/output + + + - name: Save Code Coverage + if: ${{ matrix.php == '8.0' }} + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.3/php-coveralls.phar + php php-coveralls.phar --verbose --config tests/.coveralls.yml diff --git a/src/Dibi/Drivers/PdoDriver.php b/src/Dibi/Drivers/PdoDriver.php index 4b4b54c8e..3cb595739 100644 --- a/src/Dibi/Drivers/PdoDriver.php +++ b/src/Dibi/Drivers/PdoDriver.php @@ -12,6 +12,7 @@ use Dibi; use Dibi\Helpers; use PDO; +use PDOException; /** @@ -57,8 +58,8 @@ public function __construct(array $config) $this->connection = $config['resource']; unset($config['resource'], $config['pdo']); - if ($this->connection->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_SILENT) { - throw new Dibi\DriverException('PDO connection in exception or warning error mode is not supported.'); + if ($this->connection->getAttribute(PDO::ATTR_ERRMODE) === PDO::ERRMODE_WARNING) { + throw new Dibi\DriverException('PDO connection in warning error mode is not supported.'); } } else { @@ -93,15 +94,18 @@ public function disconnect(): void */ public function query(string $sql): ?Dibi\ResultDriver { - $res = $this->connection->query($sql); - if ($res) { - $this->affectedRows = $res->rowCount(); - return $res->columnCount() ? $this->createResultDriver($res) : null; + try { + $res = $this->connection->query($sql); + if ($res) { + $this->affectedRows = $res->rowCount(); + return $res->columnCount() ? $this->createResultDriver($res) : null; + } + [$sqlState, $code, $message] = $this->connection->errorInfo(); + } catch (PDOException $e) { + [$sqlState, $code, $message] = $e->errorInfo; } - $this->affectedRows = null; - [$sqlState, $code, $message] = $this->connection->errorInfo(); $message = "SQLSTATE[$sqlState]: $message"; switch ($this->driverName) { case 'mysql': diff --git a/tests/databases.github.ini b/tests/databases.github.ini new file mode 100644 index 000000000..40aeb4641 --- /dev/null +++ b/tests/databases.github.ini @@ -0,0 +1,89 @@ +[sqlite] ; default +driver = sqlite +database = :memory: +system = sqlite + +[sqlite pdo] +driver = pdo +dsn = "sqlite::memory:" +system = sqlite + +[mysql 5.7] +driver = mysqli +host = "127.0.0.1" +database = dibi_test +username = root +password = root +port = 3306 +system = mysql + +[mysql 5.7pdo] +driver = pdo +dsn = "mysql:host=127.0.0.1;port=3306;dbname=dibi_test" +user = root +password = root +system = mysql + +[mysql 8.0] +driver = mysqli +host = "127.0.0.1" +database = dibi_test +username = root +password = root +port = 3307 +system = mysql + +[mysql 8.0pdo] +driver = pdo +dsn = "mysql:host=127.0.0.1;port=3307;dbname=dibi_test" +user = root +password = root +system = mysql + +[postgre 9.6] +driver = postgre +host = "127.0.0.1" +database = dibi_test +username = postgres +password = postgres +port = 5432 +system = postgre + +[postgre 9.6pdo] +driver = pdo +dsn = "pgsql:host=127.0.0.1;port=5432;dbname=dibi_test" +user = postgres +password = postgres +system = postgre + +[postgre 13] +driver = postgre +host = "127.0.0.1" +database = dibi_test +username = postgres +password = postgres +port = 5433 +system = postgre + +[postgre 13pdo] +driver = pdo +dsn = "pgsql:host=127.0.0.1;port=5433;dbname=dibi_test" +user = postgres +password = postgres +system = postgre + +[sqlsrv] +driver = sqlsrv +host = "localhost" +username = SA +password = "YourStrong!Passw0rd" +database = dibi_test +port = 1433 +system = sqlsrv + +;[sqlsrv pdo] +;driver = pdo +;dsn = "sqlsrv:Server=localhost,1433;Database=dibi_test" +;user = SA +;password = "YourStrong!Passw0rd" +;system = sqlsrv diff --git a/tests/dibi/PdoDriver.providedConnection.phpt b/tests/dibi/PdoDriver.providedConnection.phpt index 81d999c21..8a7079457 100644 --- a/tests/dibi/PdoDriver.providedConnection.phpt +++ b/tests/dibi/PdoDriver.providedConnection.phpt @@ -17,16 +17,14 @@ function buildPdoDriver(?int $errorMode) } -// PDO error mode: exception -Assert::exception(function () { - buildPdoDriver(PDO::ERRMODE_EXCEPTION); -}, Dibi\DriverException::class, 'PDO connection in exception or warning error mode is not supported.'); +// PDO error mode: exception is accepted +buildPdoDriver(PDO::ERRMODE_EXCEPTION); // PDO error mode: warning Assert::exception(function () { buildPdoDriver(PDO::ERRMODE_WARNING); -}, Dibi\DriverException::class, 'PDO connection in exception or warning error mode is not supported.'); +}, Dibi\DriverException::class, 'PDO connection in warning error mode is not supported.'); test('PDO error mode: explicitly set silent', function () {