From bac2257d1f572e6480df8405e244ecb7d5a54695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turcs=C3=A1n=20=C3=81d=C3=A1m?= Date: Fri, 6 Jan 2017 01:32:07 +0100 Subject: [PATCH] Added: - Create more tests to cover those that shouldn't be affected by these changes. - Add ReconnectingPDO::getAvailableDrivers - this was hidden before Fixed: - Fixes #1 Other changes: - Enriching docblocks to help IDE code assistance --- composer.json | 9 +- composer.lock | 228 ++++++++++++++------------ src/ReconnectingPDO.php | 13 +- src/ReconnectingPDOStatement.php | 69 ++++++-- test/Mock/FetchObjectTestClass.php | 24 +++ test/ReconnectingPDOStatementTest.php | 178 +++++++++++++++++++- test/ReconnectingPDOTest.php | 54 +++++- 7 files changed, 442 insertions(+), 133 deletions(-) create mode 100644 test/Mock/FetchObjectTestClass.php diff --git a/composer.json b/composer.json index bf8de6a..3472c0f 100644 --- a/composer.json +++ b/composer.json @@ -25,8 +25,15 @@ "LegoW\\ReconnectingPDO\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "LegoW\\ReconnectingPDO\\Test\\": "test/" + } + }, "require-dev": { "phpunit/phpunit": "^5.6", - "phpunit/dbunit": "^2.0" + "phpunit/dbunit": "^2.0", + "ext-pdo_sqlite": "*", + "ext-xml": "*" } } diff --git a/composer.lock b/composer.lock index 5f75121..a073b3c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "7db1854a8a4cf6907b2bfe0ccc749c48", - "content-hash": "0cd6de5d196067e37cd4f73ed50c75a9", + "hash": "bfecdbf9355b6ac849c18f81ae472442", + "content-hash": "305ca2c634e790ea5ec59b7c56d7a21e", "packages": [], "packages-dev": [ { @@ -205,16 +205,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "0.2", + "version": "0.2.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443" + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443", - "reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", + "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb", "shasum": "" }, "require": { @@ -248,20 +248,20 @@ "email": "me@mikevanriel.com" } ], - "time": "2016-06-10 07:14:17" + "time": "2016-11-25 06:54:22" }, { "name": "phpspec/prophecy", - "version": "v1.6.1", + "version": "v1.6.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0" + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0", - "reference": "58a8137754bc24b25740d4281399a4a3596058e0", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", + "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", "shasum": "" }, "require": { @@ -269,10 +269,11 @@ "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0" + "sebastian/recursion-context": "^1.0|^2.0" }, "require-dev": { - "phpspec/phpspec": "^2.0" + "phpspec/phpspec": "^2.0", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", "extra": { @@ -310,28 +311,28 @@ "spy", "stub" ], - "time": "2016-06-07 08:13:47" + "time": "2016-11-21 14:58:47" }, { "name": "phpunit/dbunit", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/dbunit.git", - "reference": "390cefcb101e07e1d6400dbdfc3b90ecf2c1279f" + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/390cefcb101e07e1d6400dbdfc3b90ecf2c1279f", - "reference": "390cefcb101e07e1d6400dbdfc3b90ecf2c1279f", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/5c35d74549c21ba55d0ea74ba89d191a51f8cf25", + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25", "shasum": "" }, "require": { "ext-pdo": "*", "ext-simplexml": "*", - "php": ">=5.4", - "phpunit/phpunit": "~4|~5", - "symfony/yaml": "~2.1|~3.0" + "php": "^5.4 || ^7.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0", + "symfony/yaml": "^2.1 || ^3.0" }, "bin": [ "dbunit" @@ -365,20 +366,20 @@ "testing", "xunit" ], - "time": "2015-11-03 11:17:01" + "time": "2016-12-02 14:39:14" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.2", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d" + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6cba06ff75a1a63a71033e1a01b89056f3af1e8d", - "reference": "6cba06ff75a1a63a71033e1a01b89056f3af1e8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a", + "reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a", "shasum": "" }, "require": { @@ -428,20 +429,20 @@ "testing", "xunit" ], - "time": "2016-11-01 05:06:24" + "time": "2016-12-20 15:22:42" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0", - "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { @@ -475,7 +476,7 @@ "filesystem", "iterator" ], - "time": "2015-06-21 13:08:43" + "time": "2016-10-03 07:40:28" }, { "name": "phpunit/php-text-template", @@ -564,16 +565,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "1.4.8", + "version": "1.4.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da" + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", - "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", + "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", "shasum": "" }, "require": { @@ -609,20 +610,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-09-15 10:49:45" + "time": "2016-11-15 14:06:22" }, { "name": "phpunit/phpunit", - "version": "5.6.2", + "version": "5.7.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "cd13b23ac5a519a4708e00736c26ee0bb28b2e01" + "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/cd13b23ac5a519a4708e00736c26ee0bb28b2e01", - "reference": "cd13b23ac5a519a4708e00736c26ee0bb28b2e01", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe", + "reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe", "shasum": "" }, "require": { @@ -633,18 +634,18 @@ "ext-xml": "*", "myclabs/deep-copy": "~1.3", "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "^4.0.1", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.3", "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "~1.1", + "sebastian/comparator": "~1.2.2", "sebastian/diff": "~1.2", - "sebastian/environment": "^1.3 || ^2.0", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/object-enumerator": "~1.0", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.0 || ^2.0", + "sebastian/object-enumerator": "~2.0", "sebastian/resource-operations": "~1.0", "sebastian/version": "~1.0|~2.0", "symfony/yaml": "~2.1|~3.0" @@ -665,7 +666,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.6.x-dev" + "dev-master": "5.7.x-dev" } }, "autoload": { @@ -691,27 +692,27 @@ "testing", "xunit" ], - "time": "2016-10-25 07:40:25" + "time": "2016-12-28 07:18:51" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2" + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", - "reference": "238d7a2723bce689c79eeac9c7d5e1d623bb9dc2", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", + "reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.6 || ^7.0", "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2" + "sebastian/exporter": "^1.2 || ^2.0" }, "conflict": { "phpunit/phpunit": "<5.4.0" @@ -750,7 +751,7 @@ "mock", "xunit" ], - "time": "2016-10-09 07:01:45" + "time": "2016-12-08 20:27:08" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -799,22 +800,22 @@ }, { "name": "sebastian/comparator", - "version": "1.2.0", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22" + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22", - "reference": "937efb279bd37a375bcadf584dec0726f84dbf22", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -859,7 +860,7 @@ "compare", "equality" ], - "time": "2015-07-26 15:48:44" + "time": "2016-11-19 09:18:40" }, { "name": "sebastian/diff", @@ -915,28 +916,28 @@ }, { "name": "sebastian/environment", - "version": "1.3.8", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.6 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" + "phpunit/phpunit": "^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -961,25 +962,25 @@ "environment", "hhvm" ], - "time": "2016-08-18 05:49:44" + "time": "2016-11-26 07:53:53" }, { "name": "sebastian/exporter", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", "shasum": "" }, "require": { "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "ext-mbstring": "*", @@ -988,7 +989,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1028,7 +1029,7 @@ "export", "exporter" ], - "time": "2016-06-17 09:04:28" + "time": "2016-11-19 08:54:04" }, { "name": "sebastian/global-state", @@ -1083,21 +1084,21 @@ }, { "name": "sebastian/object-enumerator", - "version": "1.0.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", - "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", "shasum": "" }, "require": { "php": ">=5.6", - "sebastian/recursion-context": "~1.0" + "sebastian/recursion-context": "~2.0" }, "require-dev": { "phpunit/phpunit": "~5" @@ -1105,7 +1106,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1125,20 +1126,20 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-01-28 13:25:10" + "time": "2016-11-19 07:35:10" }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", "shasum": "" }, "require": { @@ -1150,7 +1151,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1178,7 +1179,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11 19:50:13" + "time": "2016-11-19 07:33:16" }, { "name": "sebastian/resource-operations", @@ -1224,16 +1225,16 @@ }, { "name": "sebastian/version", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", - "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { @@ -1263,29 +1264,35 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-02-04 12:56:52" + "time": "2016-10-03 07:35:21" }, { "name": "symfony/yaml", - "version": "v3.1.6", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27" + "reference": "a7095af4b97a0955f85c8989106c249fa649011f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/7ff51b06c6c3d5cc6686df69004a42c69df09e27", - "reference": "7ff51b06c6c3d5cc6686df69004a42c69df09e27", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a7095af4b97a0955f85c8989106c249fa649011f", + "reference": "a7095af4b97a0955f85c8989106c249fa649011f", "shasum": "" }, "require": { "php": ">=5.5.9" }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -1312,24 +1319,24 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-10-24 18:41:13" + "time": "2016-12-10 10:07:06" }, { "name": "webmozart/assert", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308" + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308", - "reference": "bb2d123231c095735130cc8f6d31385a44c7b308", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", "shasum": "" }, "require": { - "php": "^5.3.3|^7.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { "phpunit/phpunit": "^4.6", @@ -1338,7 +1345,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.3-dev" } }, "autoload": { @@ -1362,7 +1369,7 @@ "check", "validate" ], - "time": "2016-08-09 15:02:57" + "time": "2016-11-23 20:04:58" } ], "aliases": [], @@ -1374,5 +1381,8 @@ "php": ">=5.5", "ext-pdo": "*" }, - "platform-dev": [] + "platform-dev": { + "ext-pdo_sqlite": "*", + "ext-xml": "*" + } } diff --git a/src/ReconnectingPDO.php b/src/ReconnectingPDO.php index 0b4f7fb..ff5885f 100644 --- a/src/ReconnectingPDO.php +++ b/src/ReconnectingPDO.php @@ -33,7 +33,6 @@ * @method array errorInfo() Fetch extended error information associated with the last operation on the database handle * @method mixed getAttribute(int $attribute One of the PDO::ATTR_* constants.) Retrieve a database connection attribute * @method string quote(string $string The string to be quoted, int $parameter_type = 'PDO::PARAM_STR') Quotes a string for use in a query. - * @method array getAvailableDrivers() Return an array of available PDO drivers */ class ReconnectingPDO { @@ -74,6 +73,18 @@ class ReconnectingPDO */ protected $maxReconnection; + /** + * (PHP 5 >= 5.1.3, PHP 7, PECL pdo >= 1.0.3)
+ * Return an array of available PDO drivers + * @link http://php.net/manual/en/pdo.getavailabledrivers.php + * @return array PDO::getAvailableDrivers returns an array of PDO driver names. If + * no drivers are available, it returns an empty array. + */ + public static function getAvailableDrivers() + { + return \PDO::getAvailableDrivers(); + } + /** * (PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)
* Creates a ReconnectingPDO instance representing a connection to a database diff --git a/src/ReconnectingPDOStatement.php b/src/ReconnectingPDOStatement.php index 99bd511..7559cd5 100644 --- a/src/ReconnectingPDOStatement.php +++ b/src/ReconnectingPDOStatement.php @@ -20,10 +20,22 @@ * If server has gone away it can recreate itself. Use it with great caution in cases of update or insert statements * * @author Turcsán Ádám - * @method bool execute(array $parameters = null [optional]) Executes a prepared statement - * @method bool bindParam(mixed $parameter, mixed &$variable, int $dataType = PDO::PARAM_STR [optional], int $length = null [optional], $driver_options = null [optional]) Binds a parameter to the specified variable name - * @method bool bindValue(mixed $parameter, mixed $value, int $data_type = PDO::PARAM_STR [optional]) Binds a value to a parameter + * @method bool bindParam(mixed $parameter, mixed &$variable, int $dataType = PDO::PARAM_STR, int $length = null, $driver_options = null) Binds a parameter to the specified variable name + * @method bool bindValue(mixed $parameter, mixed $value, int $data_type = PDO::PARAM_STR) Binds a value to a parameter + * @method bool closeCursor() Closes the cursor, enabling the statement to be executed again. + * @method int columnCount() Returns the number of columns in the result set + * @method void debugDumpParams() Dump an SQL prepared command + * @method string errorCode() Fetch the SQLSTATE associated with the last operation on the statement handle + * @method array errorInfo() Fetch extended error information associated with the last operation on the statement handle + * @method bool execute(array $parameters = null) Executes a prepared statement + * @method mixed fetchColumn(int $column_number = 0) Returns a single column from the next row of a result set + * @method mixed fetchObject(string $class_name = "stdClass", array $ctor_args = null) Fetches the next row and returns it as an object + * @method mixed getAttribute(int $attribute) Retrieve a statement attribute + * @method array getColumnMeta(int $column) Returns metadata for a column in a result set + * @method bool nextRowset() Advances to the next rowset in a multi-rowset statement handle * @method int rowCount() Returns the number of rows affected by the last SQL statement + * @method bool setAttribute ( int $attribute , mixed $value ) Set a statement attribute + * @method bool setFetchMode ( int $mode [PDO::FETCH_* constants] ) Set the default fetch mode for this statement

If $mode = PDO::FETCH_COLUMN, second argument: int $colnum
If $mode = PDO::FETCH_CLASS, further arguments: string $classname, array $ctorargs
If $mode = PDO::FETCH_INTO, second argument: object $object */ class ReconnectingPDOStatement { @@ -126,16 +138,15 @@ protected function call($method, &$arguments) switch ($method) { //Differenct method handlers case 'bindParam': - for($i=0; $i<5; $i++) { - ${'a'.$i} = &$arguments[$i]; + for ($i = 0; $i < 5; $i++) { + ${'a' . $i} = &$arguments[$i]; } return $this->statement->bindParam($a0, $a1, $a2, $a3, $a4); //Pre-call case 'fetch': - case 'fetchAll': case 'fetchColumn': case 'fetchObject': - $this->trackCursor($method); + $this->trackCursor(); break; case 'execute': $this->executed = true; @@ -212,6 +223,28 @@ protected function searchPosition() $this->cursor->setPosition($position); } + /** + * + * @param int $steps + */ + protected function forwardCursor($steps) + { + $position = $this->cursor->getPosition() + $steps; + while ($this->cursor->next()->getPosition() < $position) { + //Nothin to do here. + } + } + + /** + * Bind a column to a PHP variable + * + * @param mixed $column + * @param mixed $param + * @param int $type [optional] + * @param int $maxlen [optional] + * @param mixed $driverdata [optional] + * @return bool + */ public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata = null) { @@ -220,6 +253,14 @@ public function bindColumn($column, &$param, $type = null, $maxlen = null, $driverdata); } + /** + * Fetches the next row from a result set + * + * @param int $fetchType [optional] + * @param int $cursor_orientation = PDO::FETCH_ORI_NEXT + * @param int $cursor_offset = 0 + * @return mixed + */ public function fetch($fetchType = null, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = 0) { @@ -239,18 +280,19 @@ public function fetch($fetchType = null, } /** + * Returns an array containing all of the result set rows * - * @param int $fetch_style - * @param mixed $fetch_argumnet - * @param array $ctor_args + * @param int $fetch_style = \PDO::FETCH_BOTH + * @param mixed $fetch_argument [optional] + * @param array $ctor_args = [] */ public function fetchAll($fetch_style = \PDO::FETCH_BOTH, - $fetch_argumnet = null, $ctor_args = []) + $fetch_argument = null, $ctor_args = []) { $args = func_get_args(); $result = $this->call('fetchAll', $args); if (isset($this->seedData['bindColumn']) && count($this->seedData['bindColumn'])) { - foreach ($this->seedData['bindColumn'] as $name => $column) { + foreach (array_keys($this->seedData['bindColumn']) as $name) { if (is_int($name)) { $keys = array_keys($result); $this->seedData['bindColumn'][$name] = $result[count($result) - 1][$keys[$name - 1]]; @@ -259,6 +301,9 @@ public function fetchAll($fetch_style = \PDO::FETCH_BOTH, } } } + if (is_array($result)) { + $this->forwardCursor(count($result)); + } return $result; } diff --git a/test/Mock/FetchObjectTestClass.php b/test/Mock/FetchObjectTestClass.php new file mode 100644 index 0000000..5505f62 --- /dev/null +++ b/test/Mock/FetchObjectTestClass.php @@ -0,0 +1,24 @@ + + */ +class FetchObjectTestClass +{ + + public $id; + public $name; + public $value; + +} diff --git a/test/ReconnectingPDOStatementTest.php b/test/ReconnectingPDOStatementTest.php index c42d6d9..67976ad 100644 --- a/test/ReconnectingPDOStatementTest.php +++ b/test/ReconnectingPDOStatementTest.php @@ -14,6 +14,7 @@ use PDOStatement; use LegoW\ReconnectingPDO\ReconnectingPDO; use LegoW\ReconnectingPDO\ReconnectingPDOStatement; +use LegoW\ReconnectingPDO\Test\Mock\FetchObjectTestClass; /** * Description of ReconnectingPDOStatementTest @@ -23,6 +24,11 @@ class ReconnectingPDOStatementTest extends TestCase { + /** + * @var string + */ + protected $testDSN = 'sqlite::memory:'; + /** * @var \PDO */ @@ -44,11 +50,6 @@ public function setUp() $this->commonTestDB = $pdo; } - /** - * @var string - */ - protected $testDSN = 'sqlite::memory:'; - public function testConstruct() { if (version_compare(phpversion(), '7.0', '>=')) { @@ -81,12 +82,16 @@ public function testBinding() $pdo = new ReconnectingPDO($this->testDSN); $rstm = $pdo->prepare('SELECT :param, :value, 1 as column;'); $param = 'test'; - $rstm->bindValue('value', 'value', PDO::PARAM_STR); $rstm->bindParam('param', $param, PDO::PARAM_STR); + $rstm->bindValue('value', 'value', PDO::PARAM_STR); $this->assertTrue($rstm->execute()); $this->assertEquals([$param, 'value', 1], $rstm->fetch(PDO::FETCH_NUM)); + } + public function testBindColumn() + { + $pdo = new ReconnectingPDO($this->testDSN); $value = $id = null; $statement = $pdo->prepare('SELECT 11, "valuevalue" as value;'); $statement->execute(); @@ -102,6 +107,10 @@ public function testBinding() $seedData = $prop->getValue($statement); $this->assertEquals('valuevalue', $value); $this->assertEquals(11, $id); + } + + public function testBindColumnWithFetchAll() + { $newPDO = new ReconnectingPDO('', '', ''); $newPDO->setPDO($this->commonTestDB); @@ -112,9 +121,10 @@ public function testBinding() $stm->execute(); $stm->fetchAll(); + $lastIndex = (count($this->testDBData) - 1); - $this->assertEquals($this->testDBData[2]['id'], $newId); - $this->assertEquals($this->testDBData[2]['name'], $newValue); + $this->assertEquals($this->testDBData[$lastIndex]['id'], $newId); + $this->assertEquals($this->testDBData[$lastIndex]['name'], $newValue); } public function testGetPDOStatement() @@ -253,4 +263,156 @@ public function testCursor() $this->assertEquals($this->testDBData[1], $sut->fetch(\PDO::FETCH_ASSOC)); } + public function testCursorAfterFetchAll() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + /* @var $stm ReconnectingPDOStatement */ + $stm = $rpdo->query('SELECT * FROM test'); + $result = $stm->fetchAll(); + $stmCursor = new \LegoW\ReconnectingPDO\StatementCursor(); + $stmCursor->setPosition(count($result)); + + $this->assertAttributeEquals($stmCursor, 'cursor', $stm); + } + + public function testCloseCursor() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + /* @var $stm ReconnectingPDOStatement */ + $stm = $rpdo->prepare('SELECT * FROM test'); + + $stm->execute(); + $this->assertEquals($stm->fetch(\PDO::FETCH_ASSOC), $this->testDBData[0]); + $stm->closeCursor(); + $this->assertFalse($stm->fetch(\PDO::FETCH_ASSOC)); + //Reexecuting starts everything over + $stm->execute(); + $this->assertEquals($stm->fetch(\PDO::FETCH_ASSOC), $this->testDBData[0]); + } + + public function testColumnCount() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + + $this->assertSame(0, $stm->columnCount()); + $stm->execute(); + $this->assertSame(3, $stm->columnCount()); + } + + public function testDebugDumpParams() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $query = 'SELECT * FROM test'; + /* @var $stm ReconnectingPDOStatement */ + $stm = $rpdo->prepare($query); + + $debugParams = 'SQL: [' . strlen($query) . '] ' . $query . "\nParams: 0\n"; + + ob_start(); + $stm->debugDumpParams(); + $output = ob_get_contents(); + ob_end_clean(); + $this->assertSame($debugParams, $output); + } + + public function testErrorCode() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + $stm->execute(); + $this->assertSame('00000', $stm->errorCode()); + } + + public function testErrorInfo() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + $stm->execute(); + $emptyErrorInfo = [ + '00000', + null, + null + ]; + $this->assertSame($emptyErrorInfo, $stm->errorInfo()); + } + + public function testFetchColumn() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + $stm->execute(); + + $this->assertEquals($this->testDBData[0]['name'], $stm->fetchColumn(1)); + $this->assertEquals($this->testDBData[1]['id'], $stm->fetchColumn()); + } + + public function testFetchObject() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + $stm->execute(); + $testObject = new FetchObjectTestClass(); + $testObject->id = 1; + $testObject->name = 'név'; + $testObject->value = 'érték'; + $this->assertEquals($testObject, + $stm->fetchObject(FetchObjectTestClass::class)); + $this->assertInstanceOf(get_class($testObject), + $stm->fetchObject(FetchObjectTestClass::class)); + } + + public function testGetColumnMeta() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT id FROM test'); + $this->assertFalse($stm->getColumnMeta(0)); + $stm->execute(); + $this->assertArraySubset(['name' => 'id', 'table' => 'test', 'native_type' => 'integer'], + $stm->getColumnMeta(0)); + } + + public function testRowCount() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + $rpdo->beginTransaction(); + $stm = $rpdo->prepare('DELETE FROM test'); + $this->assertSame(0, $stm->rowCount()); + $stm->execute(); + $this->assertSame(count($this->testDBData), $stm->rowCount()); + $rpdo->rollBack(); + } + + public function testSetFetchMode() + { + $rpdo = new ReconnectingPDO($this->testDSN, '', ''); + $rpdo->setPDO($this->commonTestDB); + + $stm = $rpdo->prepare('SELECT * FROM test'); + $stm->setFetchMode(\PDO::FETCH_ASSOC); + $stm->execute(); + $this->assertEquals($this->testDBData[0], $stm->fetch()); + $stm->setFetchMode(\PDO::FETCH_NUM); + $this->assertEquals(array_values($this->testDBData[1]), $stm->fetch()); + } + } diff --git a/test/ReconnectingPDOTest.php b/test/ReconnectingPDOTest.php index dc05552..e1960ff 100644 --- a/test/ReconnectingPDOTest.php +++ b/test/ReconnectingPDOTest.php @@ -38,7 +38,7 @@ public function testConstruct() $this->assertAttributeEquals(3, 'maxReconnection', $rpdo); $this->assertAttributeInstanceOf(\PDO::class, 'connection', $rpdo); } - + public function testSetters() { $dsn = 'sqlite::memory:'; @@ -71,7 +71,6 @@ public function testSetters() $exception = $ex; } $this->assertNull($exception); - } public function testReconnection() @@ -202,6 +201,35 @@ public function testTransaction() $rpdo->exec('SELECT * FROM test'); } + public function testTransactionCommit() + { + $rpdo = new ReconnectingPDO('sqlite::memory:'); + + $rpdo->beginTransaction(); + $rpdo->exec('CREATE TABLE test (id int(2), name varchar(64), value varchar(255))'); + $rpdo->exec('INSERT INTO test VALUES (1, "testName", "testValue")'); + $this->assertSame(1, $rpdo->exec('SELECT * FROM test')); + $rpdo->commit(); + $this->assertSame(1, $rpdo->exec('SELECT * FROM test')); + } + + public function testErrorCode() + { + $rpdo = new ReconnectingPDO('sqlite::memory:'); + $this->assertSame('00000', $rpdo->errorCode()); + } + + public function testErrorInfo() + { + $emptyErrorInfo = [ + '00000', + null, + null + ]; + $rpdo = new ReconnectingPDO('sqlite::memory:'); + $this->assertSame($emptyErrorInfo, $rpdo->errorInfo()); + } + public function testLastInsertId() { $rpdo = new ReconnectingPDO('sqlite::memory:'); @@ -213,4 +241,26 @@ public function testLastInsertId() $this->assertEquals(2, $rpdo->lastInsertId()); } + public function testGetAndSetAttribute() + { + $rpdo = new ReconnectingPDO('sqlite::memory:'); + + $this->assertSame(\PDO::ERRMODE_EXCEPTION, $rpdo->getAttribute(\PDO::ATTR_ERRMODE)); + $rpdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_WARNING); + $this->assertSame(\PDO::ERRMODE_WARNING, $rpdo->getAttribute(\PDO::ATTR_ERRMODE)); + } + + public function testGetAvailableDrivers() + { + $this->assertTrue(is_array(ReconnectingPDO::getAvailableDrivers())); + } + + public function testInTransaction() + { + $rpdo = new ReconnectingPDO('sqlite::memory:'); + + $this->assertFalse($rpdo->inTransaction()); + $rpdo->beginTransaction(); + $this->assertTrue($rpdo->inTransaction()); + } }