diff --git a/composer.lock b/composer.lock index fa46b10..0c455af 100644 --- a/composer.lock +++ b/composer.lock @@ -196,16 +196,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.1.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", "shasum": "" }, "require": { @@ -216,7 +216,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -248,9 +248,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2024-07-01T20:03:41+00:00" }, { "name": "phar-io/manifest", @@ -372,16 +372,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "11.0.4", + "version": "11.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f" + "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4dc2b7a606073f0fb80da09842ffb068b627c38f", - "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/19b6365ab8b59a64438c0c3f4241feeb480c9861", + "reference": "19b6365ab8b59a64438c0c3f4241feeb480c9861", "shasum": "" }, "require": { @@ -438,7 +438,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.4" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.5" }, "funding": [ { @@ -446,20 +446,20 @@ "type": "github" } ], - "time": "2024-06-29T08:26:25+00:00" + "time": "2024-07-03T05:05:37+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" + "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", - "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6ed896bf50bbbfe4d504a33ed5886278c78e4a26", + "reference": "6ed896bf50bbbfe4d504a33ed5886278c78e4a26", "shasum": "" }, "require": { @@ -499,7 +499,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.1" }, "funding": [ { @@ -507,20 +507,20 @@ "type": "github" } ], - "time": "2024-02-02T06:05:04+00:00" + "time": "2024-07-03T05:06:37+00:00" }, { "name": "phpunit/php-invoker", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", - "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { @@ -563,7 +563,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -571,20 +571,20 @@ "type": "github" } ], - "time": "2024-02-02T06:05:50+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", - "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { @@ -623,7 +623,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -631,20 +631,20 @@ "type": "github" } ], - "time": "2024-02-02T06:06:56+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "7.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", - "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { @@ -683,7 +683,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -691,20 +691,20 @@ "type": "github" } ], - "time": "2024-02-02T06:08:01+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "11.2.5", + "version": "11.2.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "be9e3ed32a1287a9bfda15936cc86fef4e4cf591" + "reference": "15c7e69dec4a8f246840859e6b430bd2abeb5039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/be9e3ed32a1287a9bfda15936cc86fef4e4cf591", - "reference": "be9e3ed32a1287a9bfda15936cc86fef4e4cf591", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/15c7e69dec4a8f246840859e6b430bd2abeb5039", + "reference": "15c7e69dec4a8f246840859e6b430bd2abeb5039", "shasum": "" }, "require": { @@ -714,25 +714,25 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0", - "phpunit/php-file-iterator": "^5.0", - "phpunit/php-invoker": "^5.0", - "phpunit/php-text-template": "^4.0", - "phpunit/php-timer": "^7.0", - "sebastian/cli-parser": "^3.0", - "sebastian/code-unit": "^3.0", - "sebastian/comparator": "^6.0", - "sebastian/diff": "^6.0", - "sebastian/environment": "^7.0", - "sebastian/exporter": "^6.1.2", - "sebastian/global-state": "^7.0", - "sebastian/object-enumerator": "^6.0", - "sebastian/type": "^5.0", - "sebastian/version": "^5.0" + "phpunit/php-code-coverage": "^11.0.5", + "phpunit/php-file-iterator": "^5.0.1", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.0.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.0.1", + "sebastian/version": "^5.0.1" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -775,7 +775,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.5" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.2.7" }, "funding": [ { @@ -791,20 +791,20 @@ "type": "tidelift" } ], - "time": "2024-06-20T13:11:31+00:00" + "time": "2024-07-10T11:50:09+00:00" }, { "name": "sebastian/cli-parser", - "version": "3.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/00a74d5568694711f0222e54fb281e1d15fdf04a", - "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { @@ -840,7 +840,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -848,20 +848,20 @@ "type": "github" } ], - "time": "2024-03-02T07:26:58+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", - "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", "shasum": "" }, "require": { @@ -897,7 +897,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" }, "funding": [ { @@ -905,20 +905,20 @@ "type": "github" } ], - "time": "2024-02-02T05:50:41+00:00" + "time": "2024-07-03T04:44:28+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", - "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { @@ -953,7 +953,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -961,20 +961,20 @@ "type": "github" } ], - "time": "2024-02-02T05:52:17+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "6.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" + "reference": "131942b86d3587291067a94f295498ab6ac79c20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", - "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/131942b86d3587291067a94f295498ab6ac79c20", + "reference": "131942b86d3587291067a94f295498ab6ac79c20", "shasum": "" }, "require": { @@ -1030,7 +1030,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.1" }, "funding": [ { @@ -1038,20 +1038,20 @@ "type": "github" } ], - "time": "2024-02-02T05:53:45+00:00" + "time": "2024-07-03T04:48:07+00:00" }, { "name": "sebastian/complexity", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "88a434ad86150e11a606ac4866b09130712671f0" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", - "reference": "88a434ad86150e11a606ac4866b09130712671f0", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { @@ -1088,7 +1088,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -1096,20 +1096,20 @@ "type": "github" } ], - "time": "2024-02-02T05:55:19+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "6.0.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ab83243ecc233de5655b76f577711de9f842e712" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712", - "reference": "ab83243ecc233de5655b76f577711de9f842e712", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { @@ -1155,7 +1155,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -1163,20 +1163,20 @@ "type": "github" } ], - "time": "2024-03-02T07:30:33+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "7.1.0", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4eb3a442574d0e9d141aab209cd4aaf25701b09a", - "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { @@ -1191,7 +1191,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "7.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -1219,7 +1219,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, "funding": [ { @@ -1227,20 +1227,20 @@ "type": "github" } ], - "time": "2024-03-23T08:56:34+00:00" + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "6.1.2", + "version": "6.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "507d2333cbc4e6ea248fbda2d45ee1511e03da13" + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/507d2333cbc4e6ea248fbda2d45ee1511e03da13", - "reference": "507d2333cbc4e6ea248fbda2d45ee1511e03da13", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", "shasum": "" }, "require": { @@ -1297,7 +1297,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" }, "funding": [ { @@ -1305,20 +1305,20 @@ "type": "github" } ], - "time": "2024-06-18T11:19:56+00:00" + "time": "2024-07-03T04:56:19+00:00" }, { "name": "sebastian/global-state", - "version": "7.0.1", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", - "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { @@ -1359,7 +1359,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -1367,20 +1367,20 @@ "type": "github" } ], - "time": "2024-03-02T07:32:10+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", - "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { @@ -1417,7 +1417,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -1425,20 +1425,20 @@ "type": "github" } ], - "time": "2024-02-02T06:00:36+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "6.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", - "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { @@ -1475,7 +1475,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -1483,20 +1483,20 @@ "type": "github" } ], - "time": "2024-02-02T06:01:29+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "4.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", - "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { @@ -1531,7 +1531,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -1539,20 +1539,20 @@ "type": "github" } ], - "time": "2024-02-02T06:02:18+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "6.0.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2f15508e17af4ea35129bbc32ce28a814d9c7426" + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2f15508e17af4ea35129bbc32ce28a814d9c7426", - "reference": "2f15508e17af4ea35129bbc32ce28a814d9c7426", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { @@ -1595,7 +1595,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -1603,20 +1603,20 @@ "type": "github" } ], - "time": "2024-06-17T05:22:57+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { "name": "sebastian/type", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", - "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb6a6566f9589e86661291d13eba708cce5eb4aa", + "reference": "fb6a6566f9589e86661291d13eba708cce5eb4aa", "shasum": "" }, "require": { @@ -1652,7 +1652,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/5.0.1" }, "funding": [ { @@ -1660,20 +1660,20 @@ "type": "github" } ], - "time": "2024-02-02T06:09:34+00:00" + "time": "2024-07-03T05:11:49+00:00" }, { "name": "sebastian/version", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", - "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/45c9debb7d039ce9b97de2f749c2cf5832a06ac4", + "reference": "45c9debb7d039ce9b97de2f749c2cf5832a06ac4", "shasum": "" }, "require": { @@ -1706,7 +1706,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/version/tree/5.0.1" }, "funding": [ { @@ -1714,7 +1714,7 @@ "type": "github" } ], - "time": "2024-02-02T06:10:47+00:00" + "time": "2024-07-03T05:13:08+00:00" }, { "name": "square/pjson", diff --git a/src/AutoId.php b/src/AutoId.php index 60ddcba..7660f95 100644 --- a/src/AutoId.php +++ b/src/AutoId.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Configuration.php b/src/Configuration.php index 01a4598..ddd1b8c 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -1,8 +1,16 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; +use Exception; use PDO; +use PhpOption\{None, Option, Some}; /** * Common configuration for the document library @@ -20,9 +28,6 @@ class Configuration */ public static int $idStringLength = 16; - /** @var string The data source name (DSN) of the connection string */ - public static string $pdoDSN = ''; - /** @var string|null The username to use to establish a data connection (use env PDO_DOC_USERNAME if possible) */ public static ?string $username = null; @@ -32,41 +37,71 @@ class Configuration /** @var array|null Options to use for connections (driver-specific) */ public static ?array $options = null; - /** @var Mode|null The mode in which the library is operating (filled after first connection if not configured) */ - public static ?Mode $mode = null; + /** @var Option The mode in which the library is operating */ + public static Option $_mode; + + /** @var Option The data source name (DSN) of the connection string */ + private static Option $_pdoDSN; /** @var PDO|null The PDO instance to use for database commands */ private static ?PDO $_pdo = null; + /** + * Use a Data Source Name (DSN) + * + * @param string $dsn The data source name to use (driver:[parameters]) + * @throws DocumentException If a DSN does not start with `pgsql:` or `sqlite:` + */ + public static function useDSN(string $dsn): void + { + if (empty($dsn)) { + self::$_mode = self::$_pdoDSN = None::create(); + } else { + self::$_mode = Some::create(Mode::deriveFromDSN($dsn)); + self::$_pdoDSN = Some::create($dsn); + } + } + /** * Retrieve a new connection to the database * * @return PDO A new connection to the SQLite database with foreign key support enabled - * @throws DocumentException If this is called before a connection string is set + * @throws Exception If this is called before a connection string is set */ public static function dbConn(): PDO { if (is_null(self::$_pdo)) { - if (empty(self::$pdoDSN)) { - throw new DocumentException('Please provide a data source name (DSN) before attempting data access'); - } - self::$_pdo = new PDO(self::$pdoDSN, $_ENV['PDO_DOC_USERNAME'] ?? self::$username, + $dsn = (self::$_pdoDSN ?? None::create())->getOrThrow( + new DocumentException('Please provide a data source name (DSN) before attempting data access')); + self::$_pdo = new PDO($dsn, $_ENV['PDO_DOC_USERNAME'] ?? self::$username, $_ENV['PDO_DOC_PASSWORD'] ?? self::$password, self::$options); - - if (is_null(self::$mode)) { - $driver = self::$_pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - self::$mode = match ($driver) { - 'pgsql' => Mode::PgSQL, - 'sqlite' => Mode::SQLite, - default => throw new DocumentException( - "Unsupported driver $driver: this library currently supports PostgreSQL and SQLite") - }; - } } return self::$_pdo; } + /** + * Retrieve the mode for the current database connection + * + * @return Mode The mode for the current database connection + * @throws Exception If the database mode has not been set + */ + public static function mode(?string $process = null): Mode + { + return self::$_mode->getOrThrow( + new DocumentException('Database mode not set' . (is_null($process) ? '' : "; cannot $process"))); + } + + /** + * You probably don't mean to be calling this; it is here for testing only + * + * @param Mode|null $mode The mode to set + */ + public static function overrideMode(?Mode $mode): void + { + self::$_mode = Option::fromValue($mode); + } + /** * Clear the current PDO instance */ diff --git a/src/Count.php b/src/Count.php index 8254d74..23cf2e5 100644 --- a/src/Count.php +++ b/src/Count.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Custom.php b/src/Custom.php index d2e6cfd..2e25862 100644 --- a/src/Custom.php +++ b/src/Custom.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Definition.php b/src/Definition.php index 60ab363..72b975d 100644 --- a/src/Definition.php +++ b/src/Definition.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Delete.php b/src/Delete.php index d325724..b5eba2d 100644 --- a/src/Delete.php +++ b/src/Delete.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Document.php b/src/Document.php index ad645d4..83c5ae2 100644 --- a/src/Document.php +++ b/src/Document.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; @@ -18,7 +24,7 @@ class Document { $doInsert = fn() => Custom::nonQuery(Query::insert($tableName), Parameters::json(':data', $document)); - if (Configuration::$autoId == AutoId::None) { + if (Configuration::$autoId === AutoId::None) { $doInsert(); return; } diff --git a/src/DocumentException.php b/src/DocumentException.php index 6e39c68..5fc5fb9 100644 --- a/src/DocumentException.php +++ b/src/DocumentException.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/DocumentIndex.php b/src/DocumentIndex.php index 0728657..d51b728 100644 --- a/src/DocumentIndex.php +++ b/src/DocumentIndex.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/DocumentList.php b/src/DocumentList.php index 5c4c011..2fcb95c 100644 --- a/src/DocumentList.php +++ b/src/DocumentList.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Exists.php b/src/Exists.php index 74142bc..3eac9c3 100644 --- a/src/Exists.php +++ b/src/Exists.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Field.php b/src/Field.php index 745c1aa..985bd8e 100644 --- a/src/Field.php +++ b/src/Field.php @@ -1,7 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; +use Exception; + /** * Criteria for a field WHERE clause */ @@ -48,19 +56,19 @@ class Field * Get the WHERE clause fragment for this parameter * * @return string The WHERE clause fragment for this parameter - * @throws DocumentException If the database mode has not been set + * @throws Exception|DocumentException If the database mode has not been set */ public function toWhere(): string { - $fieldName = ($this->qualifier == '' ? '' : "$this->qualifier.") . 'data' . match (true) { + $mode = Configuration::mode('make field WHERE clause'); + $fieldName = (empty($this->qualifier) ? '' : "$this->qualifier.") . 'data' . match (true) { !str_contains($this->fieldName, '.') => "->>'$this->fieldName'", - Configuration::$mode == Mode::PgSQL => "#>>'{" . implode(',', explode('.', $this->fieldName)) . "}'", - Configuration::$mode == Mode::SQLite => "->>'" . implode("'->>'", explode('.', $this->fieldName)) . "'", - default => throw new DocumentException('Database mode not set; cannot make field WHERE clause') + $mode === Mode::PgSQL => "#>>'{" . implode(',', explode('.', $this->fieldName)) . "}'", + $mode === Mode::SQLite => "->>'" . implode("'->>'", explode('.', $this->fieldName)) . "'" }; - $fieldPath = match (Configuration::$mode) { + $fieldPath = match ($mode) { Mode::PgSQL => match (true) { - $this->op == Op::BT => is_numeric($this->value[0]) ? "($fieldName)::numeric" : $fieldName, + $this->op === Op::BT => is_numeric($this->value[0]) ? "($fieldName)::numeric" : $fieldName, is_numeric($this->value) => "($fieldName)::numeric", default => $fieldName }, @@ -71,7 +79,7 @@ class Field Op::BT => " {$this->paramName}min AND {$this->paramName}max", default => " $this->paramName" }; - return $fieldPath . ' ' . $this->op->toString() . $criteria; + return $fieldPath . ' ' . $this->op->toSQL() . $criteria; } /** diff --git a/src/FieldMatch.php b/src/FieldMatch.php index 6cb7b6d..9658508 100644 --- a/src/FieldMatch.php +++ b/src/FieldMatch.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; @@ -18,7 +24,7 @@ enum FieldMatch * * @return string The SQL keyword for this enumeration value */ - public function toString(): string + public function toSQL(): string { return match ($this) { FieldMatch::All => 'AND', diff --git a/src/Find.php b/src/Find.php index cdfda23..c283f4e 100644 --- a/src/Find.php +++ b/src/Find.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Mapper/ArrayMapper.php b/src/Mapper/ArrayMapper.php index 62f1286..baaf9c1 100644 --- a/src/Mapper/ArrayMapper.php +++ b/src/Mapper/ArrayMapper.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; @@ -7,9 +13,7 @@ namespace BitBadger\PDODocument\Mapper; */ class ArrayMapper implements Mapper { - /** - * @inheritDoc - */ + /** @inheritDoc */ public function map(array $result): array { return $result; diff --git a/src/Mapper/CountMapper.php b/src/Mapper/CountMapper.php index a2922a7..91695d3 100644 --- a/src/Mapper/CountMapper.php +++ b/src/Mapper/CountMapper.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; @@ -7,9 +13,7 @@ namespace BitBadger\PDODocument\Mapper; */ class CountMapper implements Mapper { - /** - * @inheritDoc - */ + /** @inheritDoc */ public function map(array $result): int { return (int) $result[0]; diff --git a/src/Mapper/DocumentMapper.php b/src/Mapper/DocumentMapper.php index c6df7bd..70a2f16 100644 --- a/src/Mapper/DocumentMapper.php +++ b/src/Mapper/DocumentMapper.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; diff --git a/src/Mapper/ExistsMapper.php b/src/Mapper/ExistsMapper.php index 7668318..2a3f63c 100644 --- a/src/Mapper/ExistsMapper.php +++ b/src/Mapper/ExistsMapper.php @@ -1,8 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; -use BitBadger\PDODocument\{Configuration, DocumentException, Mode}; +use BitBadger\PDODocument\{Configuration, Mode}; +use Exception; /** * Map an EXISTS result to a boolean value @@ -11,14 +18,13 @@ class ExistsMapper implements Mapper { /** * @inheritDoc - * @throws DocumentException If the database mode has not been set + * @throws Exception If the database mode has not been set */ public function map(array $result): bool { - return match (Configuration::$mode) { + return match (Configuration::mode('map existence result')) { Mode::PgSQL => (bool)$result[0], - Mode::SQLite => (int)$result[0] > 0, - default => throw new DocumentException('Database mode not set; cannot map existence result'), + Mode::SQLite => (int)$result[0] > 0 }; } } diff --git a/src/Mapper/Mapper.php b/src/Mapper/Mapper.php index 5ed0ff2..d0af9ca 100644 --- a/src/Mapper/Mapper.php +++ b/src/Mapper/Mapper.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; diff --git a/src/Mapper/StringMapper.php b/src/Mapper/StringMapper.php index c923fc5..60ffbd2 100644 --- a/src/Mapper/StringMapper.php +++ b/src/Mapper/StringMapper.php @@ -1,9 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Mapper; /** - * Map a string result from the + * Map a string result from the named field * * @implements Mapper */ diff --git a/src/Mode.php b/src/Mode.php index f6e21c7..ded0ec6 100644 --- a/src/Mode.php +++ b/src/Mode.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; @@ -12,4 +18,19 @@ enum Mode /** Storing documents in a SQLite database */ case SQLite; + + /** + * Derive the mode from the Data Source Name (DSN) + * + * @return Mode The database mode based on the DSN + * @throws DocumentException If the DSN does not start with `pgsql:` or `sqlite:` + */ + public static function deriveFromDSN(string $dsn): Mode + { + return match (true) { + str_starts_with($dsn, 'pgsql:') => Mode::PgSQL, + str_starts_with($dsn, 'sqlite:') => Mode::SQLite, + default => throw new DocumentException('This library currently supports PostgreSQL and SQLite') + }; + } } diff --git a/src/Op.php b/src/Op.php index 9352fb9..6950dbb 100644 --- a/src/Op.php +++ b/src/Op.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; @@ -27,11 +33,11 @@ enum Op case NEX; /** - * Get the string representation of this operator + * Get the SQL representation of this operator * * @return string The operator to use in SQL statements */ - public function toString(): string + public function toSQL(): string { return match ($this) { Op::EQ => "=", diff --git a/src/Parameters.php b/src/Parameters.php index 63f351c..5cea9d9 100644 --- a/src/Parameters.php +++ b/src/Parameters.php @@ -1,7 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; +use Exception; + /** * Functions to create parameters for queries */ @@ -57,7 +65,7 @@ class Parameters public static function nameFields(array $fields): array { for ($idx = 0; $idx < sizeof($fields); $idx++) { - if ($fields[$idx]->paramName == '') $fields[$idx]->paramName = ":field$idx"; + if (empty($fields[$idx]->paramName)) $fields[$idx]->paramName = ":field$idx"; } return $fields; } @@ -80,20 +88,18 @@ class Parameters * @param string $paramName The name of the parameter for the field names * @param array|string[] $fieldNames The names of the fields for the parameter * @return array An associative array of parameter/value pairs for the field names - * @throws DocumentException If the database mode has not been set + * @throws Exception If the database mode has not been set */ public static function fieldNames(string $paramName, array $fieldNames): array { - switch (Configuration::$mode) { - case Mode::PgSQL: - return [$paramName => "{" . implode(",", $fieldNames) . "}"]; - case Mode::SQLite: - $it = []; - $idx = 0; - foreach ($fieldNames as $field) $it[$paramName . $idx++] = "$.$field"; - return $it; - default: - throw new DocumentException('Database mode not set; cannot generate field name parameters'); - } + $mode = Configuration::mode('generate field name parameters'); + + if ($mode === Mode::PgSQL) return [$paramName => "{" . implode(",", $fieldNames) . "}"]; + + // else SQLite + $it = []; + $idx = 0; + foreach ($fieldNames as $field) $it[$paramName . $idx++] = "$.$field"; + return $it; } } diff --git a/src/Patch.php b/src/Patch.php index f8e2737..6e862a8 100644 --- a/src/Patch.php +++ b/src/Patch.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/src/Query.php b/src/Query.php index 82f6824..15d19af 100644 --- a/src/Query.php +++ b/src/Query.php @@ -1,7 +1,14 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; +use Exception; use Random\RandomException; /** @@ -30,8 +37,7 @@ class Query */ public static function whereByFields(array $fields, ?FieldMatch $match = null): string { - return implode(' ' . ($match ?? FieldMatch::All)->toString() . ' ', - array_map(fn($it) => $it->toWhere(), $fields)); + return implode(' ' . ($match ?? FieldMatch::All)->toSQL() . ' ', array_map(fn($it) => $it->toWhere(), $fields)); } /** @@ -53,11 +59,11 @@ class Query * * @param string $paramName The name of the parameter (optional; defaults to `:criteria`) * @return string The WHERE clause fragment for a JSON containment query - * @throws DocumentException If the database mode is not PostgreSQL + * @throws Exception|DocumentException If the database mode is not PostgreSQL */ public static function whereDataContains(string $paramName = ':criteria'): string { - if (Configuration::$mode <> Mode::PgSQL) { + if (Configuration::mode() <> Mode::PgSQL) { throw new DocumentException('JSON containment is only supported on PostgreSQL'); } return "data @> $paramName"; @@ -68,11 +74,11 @@ class Query * * @param string $paramName The name of the parameter (optional; defaults to `:path`) * @return string The WHERE clause fragment for a JSON Path match query - * @throws DocumentException If the database mode is not PostgreSQL + * @throws Exception|DocumentException If the database mode is not PostgreSQL */ public static function whereJsonPathMatches(string $paramName = ':path'): string { - if (Configuration::$mode <> Mode::PgSQL) { + if (Configuration::mode() <> Mode::PgSQL) { throw new DocumentException('JSON Path matching is only supported on PostgreSQL'); } return "jsonb_path_exists(data, $paramName::jsonpath)"; @@ -84,13 +90,13 @@ class Query * @param string $tableName The name of the table into which the document will be inserted * @param AutoId|null $autoId The version of automatic ID query to generate (optional, defaults to None) * @return string The `INSERT` statement to insert a document - * @throws DocumentException If the database mode is not set + * @throws Exception|DocumentException If the database mode is not set */ public static function insert(string $tableName, ?AutoId $autoId = null): string { try { - $id = Configuration::$idField; - $values = match (Configuration::$mode) { + $id = Configuration::$idField; + $values = match (Configuration::mode('generate auto-ID INSERT statement')) { Mode::SQLite => match ($autoId ?? AutoId::None) { AutoId::None => ':data', AutoId::Number => "json_set(:data, '$.$id', " @@ -105,9 +111,7 @@ class Query . "FROM $tableName) || '}')::jsonb", AutoId::UUID => ":data::jsonb || '{\"$id\":\"" . AutoId::generateUUID() . "\"}'", AutoId::RandomString => ":data::jsonb || '{\"$id\":\"" . AutoId::generateRandom() . "\"}'", - }, - default => - throw new DocumentException('Database mode not set; cannot generate auto-ID INSERT statement'), + } }; return "INSERT INTO $tableName VALUES ($values)"; } catch (RandomException $ex) { diff --git a/src/Query/Count.php b/src/Query/Count.php index 7efed68..25c9759 100644 --- a/src/Query/Count.php +++ b/src/Query/Count.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; diff --git a/src/Query/Definition.php b/src/Query/Definition.php index 6c94f01..e6ef53b 100644 --- a/src/Query/Definition.php +++ b/src/Query/Definition.php @@ -1,8 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; use BitBadger\PDODocument\{Configuration, DocumentException, DocumentIndex, Mode}; +use Exception; /** * Queries to define tables and indexes @@ -14,14 +21,13 @@ class Definition * * @param string $name The name of the table (including schema, if applicable) * @return string The CREATE TABLE statement for the document table - * @throws DocumentException If the database mode has not been set + * @throws Exception If the database mode has not been set */ public static function ensureTable(string $name): string { - $dataType = match (Configuration::$mode) { + $dataType = match (Configuration::mode('make create table statement')) { Mode::PgSQL => 'JSONB', - Mode::SQLite => 'TEXT', - default => throw new DocumentException('Database mode not set; cannot make create table statement') + Mode::SQLite => 'TEXT' }; return "CREATE TABLE IF NOT EXISTS $name (data $dataType NOT NULL)"; } @@ -35,7 +41,7 @@ class Definition private static function splitSchemaAndTable(string $tableName): array { $parts = explode('.', $tableName); - return sizeof($parts) == 1 ? ["", $tableName] : [$parts[0], $parts[1]]; + return sizeof($parts) === 1 ? ["", $tableName] : [$parts[0], $parts[1]]; } /** @@ -51,7 +57,7 @@ class Definition [, $tbl] = self::splitSchemaAndTable($tableName); $jsonFields = implode(', ', array_map(function (string $field) { $parts = explode(' ', $field); - $fieldName = sizeof($parts) == 1 ? $field : $parts[0]; + $fieldName = sizeof($parts) === 1 ? $field : $parts[0]; $direction = sizeof($parts) < 2 ? "" : " $parts[1]"; return "(data->>'$fieldName')$direction"; }, $fields)); @@ -75,16 +81,16 @@ class Definition * @param string $tableName The name of the table on which the document index should be created * @param DocumentIndex $indexType The type of index to be created * @return string The SQL statement to create an index on JSON documents in the specified table - * @throws DocumentException If the database mode is not PostgreSQL + * @throws Exception|DocumentException If the database mode is not PostgreSQL */ public static function ensureDocumentIndexOn(string $tableName, DocumentIndex $indexType): string { - if (Configuration::$mode <> Mode::PgSQL) { + if (Configuration::mode() <> Mode::PgSQL) { throw new DocumentException('Document indexes are only supported on PostgreSQL'); } [, $tbl] = self::splitSchemaAndTable($tableName); $extraOps = match ($indexType) { - DocumentIndex::Full => '', + DocumentIndex::Full => '', DocumentIndex::Optimized => ' jsonb_path_ops' }; return "CREATE INDEX IF NOT EXISTS idx_{$tbl}_document ON $tableName USING GIN (data$extraOps)"; diff --git a/src/Query/Delete.php b/src/Query/Delete.php index f043bd7..b643dd8 100644 --- a/src/Query/Delete.php +++ b/src/Query/Delete.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; diff --git a/src/Query/Exists.php b/src/Query/Exists.php index f6eb305..35fcc5c 100644 --- a/src/Query/Exists.php +++ b/src/Query/Exists.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; diff --git a/src/Query/Find.php b/src/Query/Find.php index c649208..a6627e9 100644 --- a/src/Query/Find.php +++ b/src/Query/Find.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; diff --git a/src/Query/Patch.php b/src/Query/Patch.php index d320735..6aa15ca 100644 --- a/src/Query/Patch.php +++ b/src/Query/Patch.php @@ -1,8 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; use BitBadger\PDODocument\{Configuration, DocumentException, Field, FieldMatch, Mode, Query}; +use Exception; /** * Queries to perform partial updates on documents @@ -15,14 +22,13 @@ class Patch * @param string $tableName The name of the table in which documents should be patched * @param string $whereClause The body of the WHERE clause to use in the UPDATE statement * @return string The UPDATE statement to perform the patch - * @throws DocumentException If the database mode has not been set + * @throws Exception If the database mode has not been set */ public static function update(string $tableName, string $whereClause): string { - $setValue = match (Configuration::$mode) { + $setValue = match (Configuration::mode('make patch statement')) { Mode::PgSQL => 'data || :data', - Mode::SQLite => 'json_patch(data, json(:data))', - default => throw new DocumentException('Database mode not set; cannot make patch statement') + Mode::SQLite => 'json_patch(data, json(:data))' }; return "UPDATE $tableName SET data = $setValue WHERE $whereClause"; } diff --git a/src/Query/RemoveFields.php b/src/Query/RemoveFields.php index a35c641..04935c8 100644 --- a/src/Query/RemoveFields.php +++ b/src/Query/RemoveFields.php @@ -1,8 +1,15 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument\Query; use BitBadger\PDODocument\{Configuration, DocumentException, Field, FieldMatch, Mode, Query}; +use Exception; /** * Queries to remove fields from documents @@ -20,20 +27,16 @@ class RemoveFields * @param array $parameters The parameter list for the query * @param string $whereClause The body of the WHERE clause for the update * @return string The UPDATE statement to remove fields from a JSON document - * @throws DocumentException If the database mode has not been set + * @throws Exception If the database mode has not been set */ public static function update(string $tableName, array $parameters, string $whereClause): string { - switch (Configuration::$mode) { - case Mode::PgSQL: - return "UPDATE $tableName SET data = data - " . array_keys($parameters)[0] - . "::text[] WHERE $whereClause"; - case Mode::SQLite: - $paramNames = implode(', ', array_keys($parameters)); - return "UPDATE $tableName SET data = json_remove(data, $paramNames) WHERE $whereClause"; - default: - throw new DocumentException('Database mode not set; cannot generate field removal query'); - } + return match (Configuration::mode('generate field removal query')) { + Mode::PgSQL => "UPDATE $tableName SET data = data - " . array_keys($parameters)[0] + . "::text[] WHERE $whereClause", + Mode::SQLite => "UPDATE $tableName SET data = json_remove(data, " . implode(', ', array_keys($parameters)) + . ") WHERE $whereClause" + }; } /** diff --git a/src/RemoveFields.php b/src/RemoveFields.php index 1885bfe..d719937 100644 --- a/src/RemoveFields.php +++ b/src/RemoveFields.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace BitBadger\PDODocument; diff --git a/tests/PjsonDocument.php b/tests/PjsonDocument.php index 79c2cd0..e085b51 100644 --- a/tests/PjsonDocument.php +++ b/tests/PjsonDocument.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test; diff --git a/tests/PjsonId.php b/tests/PjsonId.php index 54a7499..0e5de4e 100644 --- a/tests/PjsonId.php +++ b/tests/PjsonId.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test; diff --git a/tests/integration/NumDocument.php b/tests/integration/NumDocument.php index 664f3bb..c85b86c 100644 --- a/tests/integration/NumDocument.php +++ b/tests/integration/NumDocument.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration; diff --git a/tests/integration/SubDocument.php b/tests/integration/SubDocument.php index 3c5eb58..5aaf1f7 100644 --- a/tests/integration/SubDocument.php +++ b/tests/integration/SubDocument.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration; diff --git a/tests/integration/TestDocument.php b/tests/integration/TestDocument.php index 8950eb0..ef86175 100644 --- a/tests/integration/TestDocument.php +++ b/tests/integration/TestDocument.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration; diff --git a/tests/integration/postgresql/CountTest.php b/tests/integration/postgresql/CountTest.php index dbdb6ae..5f67c01 100644 --- a/tests/integration/postgresql/CountTest.php +++ b/tests/integration/postgresql/CountTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/CustomTest.php b/tests/integration/postgresql/CustomTest.php index b656b51..728b958 100644 --- a/tests/integration/postgresql/CustomTest.php +++ b/tests/integration/postgresql/CustomTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/DefinitionTest.php b/tests/integration/postgresql/DefinitionTest.php index e770704..01dccb4 100644 --- a/tests/integration/postgresql/DefinitionTest.php +++ b/tests/integration/postgresql/DefinitionTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/DeleteTest.php b/tests/integration/postgresql/DeleteTest.php index cac03cc..db68256 100644 --- a/tests/integration/postgresql/DeleteTest.php +++ b/tests/integration/postgresql/DeleteTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/DocumentListTest.php b/tests/integration/postgresql/DocumentListTest.php index 7f6fd53..45511af 100644 --- a/tests/integration/postgresql/DocumentListTest.php +++ b/tests/integration/postgresql/DocumentListTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/DocumentTest.php b/tests/integration/postgresql/DocumentTest.php index 08fb4a8..e5d5979 100644 --- a/tests/integration/postgresql/DocumentTest.php +++ b/tests/integration/postgresql/DocumentTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/ExistsTest.php b/tests/integration/postgresql/ExistsTest.php index ef67b34..b508517 100644 --- a/tests/integration/postgresql/ExistsTest.php +++ b/tests/integration/postgresql/ExistsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/FindTest.php b/tests/integration/postgresql/FindTest.php index 31695fc..b04523d 100644 --- a/tests/integration/postgresql/FindTest.php +++ b/tests/integration/postgresql/FindTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/PatchTest.php b/tests/integration/postgresql/PatchTest.php index d97d9b6..467ddf4 100644 --- a/tests/integration/postgresql/PatchTest.php +++ b/tests/integration/postgresql/PatchTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/RemoveFieldsTest.php b/tests/integration/postgresql/RemoveFieldsTest.php index 772e7dc..e32f94c 100644 --- a/tests/integration/postgresql/RemoveFieldsTest.php +++ b/tests/integration/postgresql/RemoveFieldsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; diff --git a/tests/integration/postgresql/ThrowawayDb.php b/tests/integration/postgresql/ThrowawayDb.php index 8f5c11e..84e2049 100644 --- a/tests/integration/postgresql/ThrowawayDb.php +++ b/tests/integration/postgresql/ThrowawayDb.php @@ -1,8 +1,15 @@ - + * @license MIT + * @see https://github.com/Zaid-Ajaj/ThrowawayDb The origin concept + */ + +declare(strict_types=1); namespace Test\Integration\PostgreSQL; -use BitBadger\PDODocument\{AutoId, Configuration, Custom, Definition, Document, DocumentException, Mode}; +use BitBadger\PDODocument\{AutoId, Configuration, Custom, Definition, Document, DocumentException}; use Random\RandomException; use Test\Integration\{SubDocument, TestDocument}; @@ -12,21 +19,21 @@ use Test\Integration\{SubDocument, TestDocument}; class ThrowawayDb { /** @var string The table used for document manipulation */ - public const TABLE = "test_table"; + public const TABLE = 'test_table'; /** * Configure the document library for the given database (or the main PostgreSQL connection, if the database name * is not provided; this is used for creating and dropping databases) * * @param string|null $dbName The name of the database to configure (optional, defaults to env or "postgres") + * @throws DocumentException If any is encountered */ private static function configure(?string $dbName = null): void { - Configuration::$pdoDSN = sprintf("pgsql:host=%s;dbname=%s", $_ENV['PDO_DOC_PGSQL_HOST'] ?? 'localhost', - $dbName ?? $_ENV['PDO_DOC_PGSQL_DB'] ?? 'postgres'); + Configuration::useDSN(sprintf("pgsql:host=%s;dbname=%s", $_ENV['PDO_DOC_PGSQL_HOST'] ?? 'localhost', + $dbName ?? $_ENV['PDO_DOC_PGSQL_DB'] ?? 'postgres')); Configuration::$username = $_ENV['PDO_DOC_PGSQL_USER'] ?? 'postgres'; Configuration::$password = $_ENV['PDO_DOC_PGSQL_PASS'] ?? 'postgres'; - Configuration::$mode = Mode::PgSQL; Configuration::resetPDO(); } @@ -66,10 +73,9 @@ class ThrowawayDb { self::configure(); Custom::nonQuery("DROP DATABASE IF EXISTS $dbName WITH (FORCE)", []); - Configuration::$pdoDSN = ''; + Configuration::useDSN(''); Configuration::$username = null; Configuration::$password = null; - Configuration::$mode = null; Configuration::resetPDO(); } } diff --git a/tests/integration/sqlite/CountTest.php b/tests/integration/sqlite/CountTest.php index 285d4d2..0f654c7 100644 --- a/tests/integration/sqlite/CountTest.php +++ b/tests/integration/sqlite/CountTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/CustomTest.php b/tests/integration/sqlite/CustomTest.php index 3eacc68..7d47d27 100644 --- a/tests/integration/sqlite/CustomTest.php +++ b/tests/integration/sqlite/CustomTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/DefinitionTest.php b/tests/integration/sqlite/DefinitionTest.php index f89304a..a9f20a2 100644 --- a/tests/integration/sqlite/DefinitionTest.php +++ b/tests/integration/sqlite/DefinitionTest.php @@ -1,4 +1,10 @@ + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/DeleteTest.php b/tests/integration/sqlite/DeleteTest.php index e012d0b..a160e9b 100644 --- a/tests/integration/sqlite/DeleteTest.php +++ b/tests/integration/sqlite/DeleteTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/DocumentListTest.php b/tests/integration/sqlite/DocumentListTest.php index 08ff618..a2b4f09 100644 --- a/tests/integration/sqlite/DocumentListTest.php +++ b/tests/integration/sqlite/DocumentListTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/DocumentTest.php b/tests/integration/sqlite/DocumentTest.php index e69dc05..f7767df 100644 --- a/tests/integration/sqlite/DocumentTest.php +++ b/tests/integration/sqlite/DocumentTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/ExistsTest.php b/tests/integration/sqlite/ExistsTest.php index e9966ff..6b9911a 100644 --- a/tests/integration/sqlite/ExistsTest.php +++ b/tests/integration/sqlite/ExistsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/FindTest.php b/tests/integration/sqlite/FindTest.php index 661f902..b6f836b 100644 --- a/tests/integration/sqlite/FindTest.php +++ b/tests/integration/sqlite/FindTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/PatchTest.php b/tests/integration/sqlite/PatchTest.php index c87723c..cd003b3 100644 --- a/tests/integration/sqlite/PatchTest.php +++ b/tests/integration/sqlite/PatchTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/RemoveFieldsTest.php b/tests/integration/sqlite/RemoveFieldsTest.php index 9d0bd08..5972f3a 100644 --- a/tests/integration/sqlite/RemoveFieldsTest.php +++ b/tests/integration/sqlite/RemoveFieldsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; diff --git a/tests/integration/sqlite/ThrowawayDb.php b/tests/integration/sqlite/ThrowawayDb.php index ff2b1b2..b199f31 100644 --- a/tests/integration/sqlite/ThrowawayDb.php +++ b/tests/integration/sqlite/ThrowawayDb.php @@ -1,8 +1,15 @@ + * @license MIT + * @see https://github.com/Zaid-Ajaj/ThrowawayDb The origin concept + */ + +declare(strict_types=1); namespace Test\Integration\SQLite; -use BitBadger\PDODocument\{AutoId, Configuration, Definition, Document, DocumentException, Mode}; +use BitBadger\PDODocument\{AutoId, Configuration, Definition, Document, DocumentException}; use Random\RandomException; use Test\Integration\{SubDocument, TestDocument}; @@ -12,7 +19,7 @@ use Test\Integration\{SubDocument, TestDocument}; class ThrowawayDb { /** @var string The table used for document manipulation */ - public const TABLE = "test_table"; + public const TABLE = 'test_table'; /** * Create a throwaway SQLite database @@ -24,8 +31,7 @@ class ThrowawayDb public static function create(bool $withData = true): string { $fileName = sprintf('throwaway-%s.db', AutoId::generateRandom(10)); - Configuration::$pdoDSN = "sqlite:./$fileName"; - Configuration::$mode = Mode::SQLite; + Configuration::useDSN("sqlite:./$fileName"); Configuration::resetPDO(); if ($withData) { diff --git a/tests/unit/ConfigurationTest.php b/tests/unit/ConfigurationTest.php index 6eb80f7..e32b48a 100644 --- a/tests/unit/ConfigurationTest.php +++ b/tests/unit/ConfigurationTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -46,7 +52,7 @@ class ConfigurationTest extends TestCase public function testDbConnFailsWhenNoDSNSpecified(): void { $this->expectException(DocumentException::class); - Configuration::$pdoDSN = ''; + Configuration::useDSN(''); Configuration::dbConn(); } } diff --git a/tests/unit/DocumentExceptionTest.php b/tests/unit/DocumentExceptionTest.php index c068473..27df03d 100644 --- a/tests/unit/DocumentExceptionTest.php +++ b/tests/unit/DocumentExceptionTest.php @@ -1,4 +1,10 @@ + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -13,7 +19,7 @@ use PHPUnit\Framework\TestCase; #[TestDox('Document Exception (Unit tests)')] class DocumentExceptionTest extends TestCase { - public function testConstructorSucceedsWithCodeAndPriorException() + public function testConstructorSucceedsWithCodeAndPriorException(): void { $priorEx = new Exception('Uh oh'); $ex = new DocumentException('Test Exception', 17, $priorEx); @@ -23,7 +29,7 @@ class DocumentExceptionTest extends TestCase $this->assertSame($priorEx, $ex->getPrevious(), 'Prior exception not filled properly'); } - public function testConstructorSucceedsWithoutCodeAndPriorException() + public function testConstructorSucceedsWithoutCodeAndPriorException(): void { $ex = new DocumentException('Oops'); $this->assertNotNull($ex, 'The exception should not have been null'); @@ -32,14 +38,14 @@ class DocumentExceptionTest extends TestCase $this->assertNull($ex->getPrevious(), 'Prior exception should have been null'); } - public function testToStringSucceedsWithoutCode() + public function testToStringSucceedsWithoutCode(): void { $ex = new DocumentException('Test failure'); $this->assertEquals("BitBadger\PDODocument\DocumentException: Test failure\n", "$ex", 'toString not generated correctly'); } - public function testToStringSucceedsWithCode() + public function testToStringSucceedsWithCode(): void { $ex = new DocumentException('Oof', -6); $this->assertEquals("BitBadger\PDODocument\DocumentException: [-6] Oof\n", "$ex", diff --git a/tests/unit/FieldMatchTest.php b/tests/unit/FieldMatchTest.php index f7d1ea4..f2ea0f0 100644 --- a/tests/unit/FieldMatchTest.php +++ b/tests/unit/FieldMatchTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -12,13 +18,15 @@ use PHPUnit\Framework\TestCase; #[TestDox('Field Match (Unit tests)')] class FieldMatchTest extends TestCase { - public function testToStringSucceedsForAll(): void + #[TestDox('To SQL succeeds for all')] + public function testToSQLSucceedsForAll(): void { - $this->assertEquals('AND', FieldMatch::All->toString(), 'All should have returned AND'); + $this->assertEquals('AND', FieldMatch::All->toSQL(), 'All should have returned AND'); } - public function testToStringSucceedsForAny(): void + #[TestDox('To SQL succeeds for any')] + public function testToSQLSucceedsForAny(): void { - $this->assertEquals('OR', FieldMatch::Any->toString(), 'Any should have returned OR'); + $this->assertEquals('OR', FieldMatch::Any->toSQL(), 'Any should have returned OR'); } } diff --git a/tests/unit/FieldTest.php b/tests/unit/FieldTest.php index a98bb12..0289b08 100644 --- a/tests/unit/FieldTest.php +++ b/tests/unit/FieldTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -40,232 +46,232 @@ class FieldTest extends TestCase #[TestDox('To where succeeds for EX without qualifier for PostgreSQL')] public function testToWhereSucceedsForEXWithoutQualifierForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $this->assertEquals("data->>'that_field' IS NOT NULL", Field::EX('that_field')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for EX without qualifier for SQLite')] public function testToWhereSucceedsForEXWithoutQualifierForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $this->assertEquals("data->>'that_field' IS NOT NULL", Field::EX('that_field')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for NEX without qualifier for PostgreSQL')] public function testToWhereSucceedsForNEXWithoutQualifierForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $this->assertEquals("data->>'a_field' IS NULL", Field::NEX('a_field')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for NEX without qualifier for SQLite')] public function testToWhereSucceedsForNEXWithoutQualifierForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $this->assertEquals("data->>'a_field' IS NULL", Field::NEX('a_field')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT without qualifier for SQLite')] public function testToWhereSucceedsForBTWithoutQualifierForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $this->assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field::BT('age', 13, 17, '@age')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT without qualifier for PostgreSQL with numeric range')] public function testToWhereSucceedsForBTWithoutQualifierForPostgreSQLWithNumericRange(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $this->assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax", Field::BT('age', 13, 17, '@age')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT without qualifier for PostgreSQL with non-numeric range')] public function testToWhereSucceedsForBTWithoutQualifierForPostgreSQLWithNonNumericRange(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $this->assertEquals("data->>'city' BETWEEN :citymin AND :citymax", Field::BT('city', 'Atlanta', 'Chicago', ':city')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT with qualifier for SQLite')] public function testToWhereSucceedsForBTWithQualifierForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $field = Field::BT('age', 13, 17, '@age'); $field->qualifier = 'me'; $this->assertEquals("me.data->>'age' BETWEEN @agemin AND @agemax", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT with qualifier for PostgreSQL with numeric range')] public function testToWhereSucceedsForBTWithQualifierForPostgreSQLWithNumericRange(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $field = Field::BT('age', 13, 17, '@age'); $field->qualifier = 'me'; $this->assertEquals("(me.data->>'age')::numeric BETWEEN @agemin AND @agemax", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for BT with qualifier for PostgreSQL with non-numeric range')] public function testToWhereSucceedsForBTWithQualifierForPostgreSQLWithNonNumericRange(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $field = Field::BT('city', 'Atlanta', 'Chicago', ':city'); $field->qualifier = 'me'; $this->assertEquals("me.data->>'city' BETWEEN :citymin AND :citymax", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for others without qualifier for PostgreSQL')] public function testToWhereSucceedsForOthersWithoutQualifierForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $this->assertEquals("data->>'some_field' = @value", Field::EQ('some_field', '', '@value')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds for others without qualifier for SQLite')] public function testToWhereSucceedsForOthersWithoutQualifierForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $this->assertEquals("data->>'some_field' = @value", Field::EQ('some_field', '', '@value')->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with qualifier no parameter for PostgreSQL')] public function testToWhereSucceedsWithQualifierNoParameterForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $field = Field::EX('no_field'); $field->qualifier = 'test'; $this->assertEquals("test.data->>'no_field' IS NOT NULL", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with qualifier no parameter for SQLite')] public function testToWhereSucceedsWithQualifierNoParameterForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $field = Field::EX('no_field'); $field->qualifier = 'test'; $this->assertEquals("test.data->>'no_field' IS NOT NULL", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with qualifier and parameter for PostgreSQL')] public function testToWhereSucceedsWithQualifierAndParameterForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $field = Field::LE('le_field', 18, '@it'); $field->qualifier = 'q'; $this->assertEquals("(q.data->>'le_field')::numeric <= @it", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with qualifier and parameter for SQLite')] public function testToWhereSucceedsWithQualifierAndParameterForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $field = Field::LE('le_field', 18, '@it'); $field->qualifier = 'q'; $this->assertEquals("q.data->>'le_field' <= @it", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with sub-document for PostgreSQL')] public function testToWhereSucceedsWithSubDocumentForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); try { $field = Field::EQ('sub.foo.bar', 22, '@it'); $this->assertEquals("(data#>>'{sub,foo,bar}')::numeric = @it", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } #[TestDox('To where succeeds with sub-document for SQLite')] public function testToWhereSucceedsWithSubDocumentForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); try { $field = Field::EQ('sub.foo.bar', 22, '@it'); $this->assertEquals("data->>'sub'->>'foo'->>'bar' = @it", $field->toWhere(), 'WHERE fragment not generated correctly'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } diff --git a/tests/unit/Mapper/ArrayMapperTest.php b/tests/unit/Mapper/ArrayMapperTest.php index b16de99..b0537a6 100644 --- a/tests/unit/Mapper/ArrayMapperTest.php +++ b/tests/unit/Mapper/ArrayMapperTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Mapper; diff --git a/tests/unit/Mapper/CountMapperTest.php b/tests/unit/Mapper/CountMapperTest.php index cdc04f2..e59694d 100644 --- a/tests/unit/Mapper/CountMapperTest.php +++ b/tests/unit/Mapper/CountMapperTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Mapper; diff --git a/tests/unit/Mapper/DocumentMapperTest.php b/tests/unit/Mapper/DocumentMapperTest.php index 4534646..fa7bc95 100644 --- a/tests/unit/Mapper/DocumentMapperTest.php +++ b/tests/unit/Mapper/DocumentMapperTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Mapper; diff --git a/tests/unit/Mapper/ExistsMapperTest.php b/tests/unit/Mapper/ExistsMapperTest.php index 7e4eac8..25d81d4 100644 --- a/tests/unit/Mapper/ExistsMapperTest.php +++ b/tests/unit/Mapper/ExistsMapperTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Mapper; @@ -17,10 +23,10 @@ class ExistsMapperTest extends TestCase public function testMapSucceedsForPostgreSQL(): void { try { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertFalse((new ExistsMapper())->map([false, 'nope']), 'Result should have been false'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } @@ -28,17 +34,17 @@ class ExistsMapperTest extends TestCase public function testMapSucceedsForSQLite(): void { try { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertTrue((new ExistsMapper())->map([1, 'yep']), 'Result should have been true'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } public function testMapFailsWhenModeNotSet(): void { $this->expectException(DocumentException::class); - Configuration::$mode = null; + Configuration::overrideMode(null); (new ExistsMapper())->map(['0']); } } diff --git a/tests/unit/Mapper/StringMapperTest.php b/tests/unit/Mapper/StringMapperTest.php index 9bda0ca..a0805cc 100644 --- a/tests/unit/Mapper/StringMapperTest.php +++ b/tests/unit/Mapper/StringMapperTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Mapper; diff --git a/tests/unit/ModeTest.php b/tests/unit/ModeTest.php new file mode 100644 index 0000000..aaede62 --- /dev/null +++ b/tests/unit/ModeTest.php @@ -0,0 +1,39 @@ + + * @license MIT + */ + +declare(strict_types=1); + +namespace Test\Unit; + +use BitBadger\PDODocument\{DocumentException, Mode}; +use PHPUnit\Framework\Attributes\TestDox; +use PHPUnit\Framework\TestCase; + +/** + * Unit tests for the Mode enumeration + */ +#[TestDox('Mode (Unit tests)')] +class ModeTest extends TestCase +{ + #[TestDox('Derive from DSN succeeds for PostgreSQL')] + public function testDeriveFromDSNSucceedsForPostgreSQL(): void + { + $this->assertEquals(Mode::PgSQL, Mode::deriveFromDSN('pgsql:Host=localhost'), 'PostgreSQL mode incorrect'); + } + + #[TestDox('Derive from DSN succeeds for SQLite')] + public function testDeriveFromDSNSucceedsForSQLite(): void + { + $this->assertEquals(Mode::SQLite, Mode::deriveFromDSN('sqlite:data.db'), 'SQLite mode incorrect'); + } + + #[TestDox('Derive from DSN fails for MySQL')] + public function testDeriveFromDSNFailsForMySQL(): void + { + $this->expectException(DocumentException::class); + Mode::deriveFromDSN('mysql:Host=localhost'); + } +} diff --git a/tests/unit/OpTest.php b/tests/unit/OpTest.php index cac2247..120ee32 100644 --- a/tests/unit/OpTest.php +++ b/tests/unit/OpTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -12,57 +18,57 @@ use PHPUnit\Framework\TestCase; #[TestDox('Op (Unit tests)')] class OpTest extends TestCase { - #[TestDox('To string succeeds for EQ')] - public function testToStringSucceedsForEQ(): void + #[TestDox('To SQL succeeds for EQ')] + public function testToSQLSucceedsForEQ(): void { - $this->assertEquals('=', Op::EQ->toString(), 'EQ operator incorrect'); + $this->assertEquals('=', Op::EQ->toSQL(), 'EQ operator incorrect'); } - #[TestDox('To string succeeds for GT')] - public function testToStringSucceedsForGT(): void + #[TestDox('To SQL succeeds for GT')] + public function testToSQLSucceedsForGT(): void { - $this->assertEquals('>', Op::GT->toString(), 'GT operator incorrect'); + $this->assertEquals('>', Op::GT->toSQL(), 'GT operator incorrect'); } - #[TestDox('To string succeeds for GE')] - public function testToStringSucceedsForGE(): void + #[TestDox('To SQL succeeds for GE')] + public function testToSQLSucceedsForGE(): void { - $this->assertEquals('>=', Op::GE->toString(), 'GE operator incorrect'); + $this->assertEquals('>=', Op::GE->toSQL(), 'GE operator incorrect'); } - #[TestDox('To string succeeds for LT')] - public function testToStringSucceedsForLT(): void + #[TestDox('To SQL succeeds for LT')] + public function testToSQLSucceedsForLT(): void { - $this->assertEquals('<', Op::LT->toString(), 'LT operator incorrect'); + $this->assertEquals('<', Op::LT->toSQL(), 'LT operator incorrect'); } - #[TestDox('To string succeeds for LE')] - public function testToStringSucceedsForLE(): void + #[TestDox('To SQL succeeds for LE')] + public function testToSQLSucceedsForLE(): void { - $this->assertEquals('<=', Op::LE->toString(), 'LE operator incorrect'); + $this->assertEquals('<=', Op::LE->toSQL(), 'LE operator incorrect'); } - #[TestDox('To string succeeds for NE')] - public function testToStringSucceedsForNE(): void + #[TestDox('To SQL succeeds for NE')] + public function testToSQLSucceedsForNE(): void { - $this->assertEquals('<>', Op::NE->toString(), 'NE operator incorrect'); + $this->assertEquals('<>', Op::NE->toSQL(), 'NE operator incorrect'); } - #[TestDox('To string succeeds for BT')] - public function testToStringSucceedsForBT(): void + #[TestDox('To SQL succeeds for BT')] + public function testToSQLSucceedsForBT(): void { - $this->assertEquals('BETWEEN', Op::BT->toString(), 'BT operator incorrect'); + $this->assertEquals('BETWEEN', Op::BT->toSQL(), 'BT operator incorrect'); } - #[TestDox('To string succeeds for EX')] - public function testToStringSucceedsForEX(): void + #[TestDox('To SQL succeeds for EX')] + public function testToSQLSucceedsForEX(): void { - $this->assertEquals('IS NOT NULL', Op::EX->toString(), 'EX operator incorrect'); + $this->assertEquals('IS NOT NULL', Op::EX->toSQL(), 'EX operator incorrect'); } - #[TestDox('To string succeeds for NEX')] - public function testToStringSucceedsForNEX(): void + #[TestDox('To SQL succeeds for NEX')] + public function testToSQLSucceedsForNEX(): void { - $this->assertEquals('IS NULL', Op::NEX->toString(), 'NEX operator incorrect'); + $this->assertEquals('IS NULL', Op::NEX->toSQL(), 'NEX operator incorrect'); } } diff --git a/tests/unit/ParametersTest.php b/tests/unit/ParametersTest.php index 8efed4f..31b06ba 100644 --- a/tests/unit/ParametersTest.php +++ b/tests/unit/ParametersTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -91,11 +97,11 @@ class ParametersTest extends TestCase public function testFieldNamesSucceedsForPostgreSQL(): void { try { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals([':names' => "{one,two,seven}"], Parameters::fieldNames(':names', ['one', 'two', 'seven']), 'Field name parameters not correct'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } @@ -103,18 +109,18 @@ class ParametersTest extends TestCase public function testFieldNamesSucceedsForSQLite(): void { try { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals([':it0' => '$.test', ':it1' => '$.unit', ':it2' => '$.wow'], Parameters::fieldNames(':it', ['test', 'unit', 'wow']), 'Field name parameters not correct'); } finally { - Configuration::$mode = null; + Configuration::overrideMode(null); } } public function testFieldNamesFailsWhenModeNotSet(): void { $this->expectException(DocumentException::class); - Configuration::$mode = null; + Configuration::overrideMode(null); Parameters::fieldNames('', []); } } diff --git a/tests/unit/Query/CountTest.php b/tests/unit/Query/CountTest.php index 8917cea..89a2726 100644 --- a/tests/unit/Query/CountTest.php +++ b/tests/unit/Query/CountTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,7 +21,7 @@ class CountTest extends TestCase { public function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); parent::tearDown(); } @@ -27,7 +33,7 @@ class CountTest extends TestCase public function testByFieldsSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("SELECT COUNT(*) FROM somewhere WHERE data->>'errors' > :errors", Count::byFields('somewhere', [Field::GT('errors', 10, ':errors')]), 'SELECT statement not generated correctly'); @@ -36,7 +42,7 @@ class CountTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT COUNT(*) FROM the_table WHERE data @> :criteria', Count::byContains('the_table'), 'SELECT statement not generated correctly'); } @@ -51,7 +57,7 @@ class CountTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT COUNT(*) FROM a_table WHERE jsonb_path_exists(data, :path::jsonpath)', Count::byJsonPath('a_table'), 'SELECT statement not generated correctly'); } diff --git a/tests/unit/Query/DefinitionTest.php b/tests/unit/Query/DefinitionTest.php index 3b5db8f..879fa3b 100644 --- a/tests/unit/Query/DefinitionTest.php +++ b/tests/unit/Query/DefinitionTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,14 +21,14 @@ class DefinitionTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); parent::tearDown(); } #[TestDox('Ensure table succeeds for PosgtreSQL')] public function testEnsureTableSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('CREATE TABLE IF NOT EXISTS documents (data JSONB NOT NULL)', Definition::ensureTable('documents'), 'CREATE TABLE statement not generated correctly'); } @@ -30,7 +36,7 @@ class DefinitionTest extends TestCase #[TestDox('Ensure table succeeds for SQLite')] public function testEnsureTableSucceedsForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals('CREATE TABLE IF NOT EXISTS dox (data TEXT NOT NULL)', Definition::ensureTable('dox'), 'CREATE TABLE statement not generated correctly'); } @@ -63,14 +69,14 @@ class DefinitionTest extends TestCase public function testEnsureDocumentIndexOnSucceedsForSchemaAndFull(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("CREATE INDEX IF NOT EXISTS idx_tbl_document ON my.tbl USING GIN (data)", Definition::ensureDocumentIndexOn('my.tbl', DocumentIndex::Full)); } public function testEnsureDocumentIndexOnSucceedsForNoSchemaAndOptimized(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("CREATE INDEX IF NOT EXISTS idx_it_document ON it USING GIN (data jsonb_path_ops)", Definition::ensureDocumentIndexOn('it', DocumentIndex::Optimized)); } diff --git a/tests/unit/Query/DeleteTest.php b/tests/unit/Query/DeleteTest.php index 7206e3f..a9a2424 100644 --- a/tests/unit/Query/DeleteTest.php +++ b/tests/unit/Query/DeleteTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,20 +21,20 @@ class DeleteTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); } #[TestDox('By ID succeeds')] public function testByIdSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("DELETE FROM over_there WHERE data->>'id' = :id", Delete::byId('over_there'), 'DELETE statement not constructed correctly'); } public function testByFieldsSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("DELETE FROM my_table WHERE data->>'value' < :max AND data->>'value' >= :min", Delete::byFields('my_table', [Field::LT('value', 99, ':max'), Field::GE('value', 18, ':min')]), 'DELETE statement not constructed correctly'); @@ -37,7 +43,7 @@ class DeleteTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('DELETE FROM somewhere WHERE data @> :criteria', Delete::byContains('somewhere'), 'DELETE statement not constructed correctly'); } @@ -52,7 +58,7 @@ class DeleteTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('DELETE FROM here WHERE jsonb_path_exists(data, :path::jsonpath)', Delete::byJsonPath('here'), 'DELETE statement not constructed correctly'); } diff --git a/tests/unit/Query/ExistsTest.php b/tests/unit/Query/ExistsTest.php index 053e340..ffa9ab5 100644 --- a/tests/unit/Query/ExistsTest.php +++ b/tests/unit/Query/ExistsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,12 +21,12 @@ class ExistsTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); } public function testQuerySucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals('SELECT EXISTS (SELECT 1 FROM abc WHERE def)', Exists::query('abc', 'def'), 'Existence query not generated correctly'); } @@ -28,14 +34,14 @@ class ExistsTest extends TestCase #[TestDox('By ID succeeds')] public function testByIdSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("SELECT EXISTS (SELECT 1 FROM dox WHERE data->>'id' = :id)", Exists::byId('dox'), 'Existence query not generated correctly'); } public function testByFieldsSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("SELECT EXISTS (SELECT 1 FROM box WHERE data->>'status' <> :status)", Exists::byFields('box', [Field::NE('status', 'occupied', ':status')]), 'Existence query not generated correctly'); @@ -44,7 +50,7 @@ class ExistsTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT EXISTS (SELECT 1 FROM pocket WHERE data @> :criteria)', Exists::byContains('pocket'), 'Existence query not generated correctly'); } @@ -59,7 +65,7 @@ class ExistsTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT EXISTS (SELECT 1 FROM lint WHERE jsonb_path_exists(data, :path::jsonpath))', Exists::byJsonPath('lint'), 'Existence query not generated correctly'); } diff --git a/tests/unit/Query/FindTest.php b/tests/unit/Query/FindTest.php index 36677f2..76a02e3 100644 --- a/tests/unit/Query/FindTest.php +++ b/tests/unit/Query/FindTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,20 +21,20 @@ class FindTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); } #[TestDox('By ID succeeds')] public function testByIdSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("SELECT data FROM here WHERE data->>'id' = :id", Find::byId('here'), 'SELECT query not generated correctly'); } public function testByFieldsSucceeds(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("SELECT data FROM there WHERE data->>'active' = :act OR data->>'locked' = :lock", Find::byFields('there', [Field::EQ('active', true, ':act'), Field::EQ('locked', true, ':lock')], FieldMatch::Any), @@ -38,7 +44,7 @@ class FindTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT data FROM disc WHERE data @> :criteria', Find::byContains('disc'), 'SELECT query not generated correctly'); } @@ -53,7 +59,7 @@ class FindTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('SELECT data FROM light WHERE jsonb_path_exists(data, :path::jsonpath)', Find::byJsonPath('light'), 'SELECT query not generated correctly'); } diff --git a/tests/unit/Query/PatchTest.php b/tests/unit/Query/PatchTest.php index 8382730..c805681 100644 --- a/tests/unit/Query/PatchTest.php +++ b/tests/unit/Query/PatchTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,13 +21,13 @@ class PatchTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); parent::tearDown(); } #[TestDox('By ID succeeds for PostgreSQL')] public function testByIdSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("UPDATE doc_table SET data = data || :data WHERE data->>'id' = :id", Patch::byId('doc_table'), 'Patch UPDATE statement is not correct'); } @@ -29,7 +35,7 @@ class PatchTest extends TestCase #[TestDox('By ID succeeds for SQLite')] public function testByIdSucceedsForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("UPDATE my_table SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id", Patch::byId('my_table'), 'Patch UPDATE statement is not correct'); } @@ -44,7 +50,7 @@ class PatchTest extends TestCase #[TestDox('By fields succeeds for PostgreSQL')] public function testByFieldsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("UPDATE that SET data = data || :data WHERE (data->>'something')::numeric < :some", Patch::byFields('that', [Field::LT('something', 17, ':some')]), 'Patch UPDATE statement is not correct'); } @@ -52,7 +58,7 @@ class PatchTest extends TestCase #[TestDox('By fields succeeds for SQLite')] public function testByFieldsSucceedsForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals( "UPDATE a_table SET data = json_patch(data, json(:data)) WHERE data->>'something' > :it", Patch::byFields('a_table', [Field::GT('something', 17, ':it')]), 'Patch UPDATE statement is not correct'); @@ -67,7 +73,7 @@ class PatchTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('UPDATE this SET data = data || :data WHERE data @> :criteria', Patch::byContains('this'), 'Patch UPDATE statement is not correct'); } @@ -82,7 +88,7 @@ class PatchTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('UPDATE that SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)', Patch::byJsonPath('that'), 'Patch UPDATE statement is not correct'); } diff --git a/tests/unit/Query/RemoveFieldsTest.php b/tests/unit/Query/RemoveFieldsTest.php index c3b71a5..2ab9da2 100644 --- a/tests/unit/Query/RemoveFieldsTest.php +++ b/tests/unit/Query/RemoveFieldsTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit\Query; @@ -15,13 +21,13 @@ class RemoveFieldsTest extends TestCase { protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); } #[TestDox('Update succeeds for PostgreSQL')] public function testUpdateSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('UPDATE taco SET data = data - :names::text[] WHERE it = true', RemoveFields::update('taco', [':names' => "{one,two}"], 'it = true'), 'UPDATE statement not correct'); } @@ -29,7 +35,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('Update succeeds for SQLite')] public function testUpdateSucceedsForSQLite(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals('UPDATE burrito SET data = json_remove(data, :name0, :name1, :name2) WHERE a = b', RemoveFields::update('burrito', Parameters::fieldNames(':name', ['one', 'two', 'ten']), 'a = b'), 'UPDATE statement not correct'); @@ -44,7 +50,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By ID succeeds for PostgreSQL')] public function testByIdSucceedsForPostgreSQL() { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("UPDATE churro SET data = data - :bite::text[] WHERE data->>'id' = :id", RemoveFields::byId('churro', Parameters::fieldNames(':bite', ['byte'])), 'UPDATE statement not correct'); } @@ -52,7 +58,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By ID succeeds for SQLite')] public function testByIdSucceedsForSQLite() { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals("UPDATE quesadilla SET data = json_remove(data, :bite0) WHERE data->>'id' = :id", RemoveFields::byId('quesadilla', Parameters::fieldNames(':bite', ['byte'])), 'UPDATE statement not correct'); @@ -68,7 +74,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By fields succeeds for PostgreSQL')] public function testByFieldsSucceedsForPostgreSQL() { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals("UPDATE enchilada SET data = data - :sauce::text[] WHERE data->>'cheese' = :queso", RemoveFields::byFields('enchilada', [Field::EQ('cheese', 'jack', ':queso')], Parameters::fieldNames(':sauce', ['white'])), @@ -78,7 +84,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By fields succeeds for SQLite')] public function testByFieldsSucceedsForSQLite() { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); $this->assertEquals( "UPDATE chimichanga SET data = json_remove(data, :filling0) WHERE data->>'side' = :rice", RemoveFields::byFields('chimichanga', [Field::EQ('side', 'beans', ':rice')], @@ -95,7 +101,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By contains succeeds for PostgreSQL')] public function testByContainsSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals('UPDATE food SET data = data - :drink::text[] WHERE data @> :criteria', RemoveFields::byContains('food', Parameters::fieldNames(':drink', ['a', 'b'])), 'UPDATE statement not correct'); @@ -111,7 +117,7 @@ class RemoveFieldsTest extends TestCase #[TestDox('By JSON Path succeeds for PostgreSQL')] public function testByJsonPathSucceedsForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); $this->assertEquals( 'UPDATE dessert SET data = data - :cake::text[] WHERE jsonb_path_exists(data, :path::jsonpath)', RemoveFields::byJsonPath('dessert', Parameters::fieldNames(':cake', ['b', 'c'])), diff --git a/tests/unit/QueryTest.php b/tests/unit/QueryTest.php index 623e7d7..f81b2f1 100644 --- a/tests/unit/QueryTest.php +++ b/tests/unit/QueryTest.php @@ -1,4 +1,10 @@ - + * @license MIT + */ + +declare(strict_types=1); namespace Test\Unit; @@ -14,12 +20,12 @@ class QueryTest extends TestCase { protected function setUp(): void { - Configuration::$mode = Mode::SQLite; + Configuration::overrideMode(Mode::SQLite); } protected function tearDown(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); } public function testSelectFromTableSucceeds(): void @@ -63,30 +69,21 @@ class QueryTest extends TestCase public function testWhereDataContainsSucceedsWithDefaultParameter(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals('data @> :criteria', Query::whereDataContains(), - 'WHERE fragment not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals('data @> :criteria', Query::whereDataContains(), + 'WHERE fragment not constructed correctly'); } public function testWhereDataContainsSucceedsWithSpecifiedParameter(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals('data @> :it', Query::whereDataContains(':it'), - 'WHERE fragment not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals('data @> :it', Query::whereDataContains(':it'), 'WHERE fragment not constructed correctly'); } #[TestDox('Where data contains fails if not PostgreSQL')] public function testWhereDataContainsFailsIfNotPostgreSQL(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); $this->expectException(DocumentException::class); Query::whereDataContains(); } @@ -94,31 +91,23 @@ class QueryTest extends TestCase #[TestDox('Where JSON Path matches succeeds with default parameter')] public function testWhereJsonPathMatchesSucceedsWithDefaultParameter(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals('jsonb_path_exists(data, :path::jsonpath)', Query::whereJsonPathMatches(), - 'WHERE fragment not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals('jsonb_path_exists(data, :path::jsonpath)', Query::whereJsonPathMatches(), + 'WHERE fragment not constructed correctly'); } #[TestDox('Where JSON Path matches succeeds with specified parameter')] public function testWhereJsonPathMatchesSucceedsWithSpecifiedParameter(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals('jsonb_path_exists(data, :road::jsonpath)', Query::whereJsonPathMatches(':road'), - 'WHERE fragment not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals('jsonb_path_exists(data, :road::jsonpath)', Query::whereJsonPathMatches(':road'), + 'WHERE fragment not constructed correctly'); } #[TestDox('Where JSON Path matches fails if not PostgreSQL')] public function testWhereJsonPathMatchesFailsIfNotPostgreSQL(): void { - Configuration::$mode = null; + Configuration::overrideMode(null); $this->expectException(DocumentException::class); Query::whereJsonPathMatches(); } @@ -126,87 +115,60 @@ class QueryTest extends TestCase #[TestDox('Insert succeeds with no auto-ID for PostgreSQL')] public function testInsertSucceedsWithNoAutoIdForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals('INSERT INTO test_tbl VALUES (:data)', Query::insert('test_tbl'), - 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals('INSERT INTO test_tbl VALUES (:data)', Query::insert('test_tbl'), + 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with no auto-ID for SQLite')] public function testInsertSucceedsWithNoAutoIdForSQLite(): void { - Configuration::$mode = Mode::SQLite; - try { - $this->assertEquals('INSERT INTO test_tbl VALUES (:data)', Query::insert('test_tbl'), - 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + $this->assertEquals('INSERT INTO test_tbl VALUES (:data)', Query::insert('test_tbl'), + 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with auto numeric ID for PostgreSQL')] public function testInsertSucceedsWithAutoNumericIdForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; - try { - $this->assertEquals( - "INSERT INTO test_tbl VALUES (:data::jsonb || ('{\"id\":' " - . "|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM test_tbl) || '}')::jsonb)", - Query::insert('test_tbl', AutoId::Number), 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $this->assertEquals( + "INSERT INTO test_tbl VALUES (:data::jsonb || ('{\"id\":' " + . "|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM test_tbl) || '}')::jsonb)", + Query::insert('test_tbl', AutoId::Number), 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with auto numeric ID for SQLite')] public function testInsertSucceedsWithAutoNumericIdForSQLite(): void { - Configuration::$mode = Mode::SQLite; - try { - $this->assertEquals( - "INSERT INTO test_tbl VALUES (json_set(:data, '$.id', " - . "(SELECT coalesce(max(data->>'id'), 0) + 1 FROM test_tbl)))", - Query::insert('test_tbl', AutoId::Number), 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + $this->assertEquals( + "INSERT INTO test_tbl VALUES (json_set(:data, '$.id', " + . "(SELECT coalesce(max(data->>'id'), 0) + 1 FROM test_tbl)))", + Query::insert('test_tbl', AutoId::Number), 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with auto UUID for PostgreSQL')] public function testInsertSucceedsWithAutoUuidForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; - try { - $query = Query::insert('test_tbl', AutoId::UUID); - $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (:data::jsonb || '{\"id\":\"", $query, - 'INSERT statement not constructed correctly'); - $this->assertStringEndsWith("\"}')", $query, 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + Configuration::overrideMode(Mode::PgSQL); + $query = Query::insert('test_tbl', AutoId::UUID); + $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (:data::jsonb || '{\"id\":\"", $query, + 'INSERT statement not constructed correctly'); + $this->assertStringEndsWith("\"}')", $query, 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with auto UUID for SQLite')] public function testInsertSucceedsWithAutoUuidForSQLite(): void { - Configuration::$mode = Mode::SQLite; - try { - $query = Query::insert('test_tbl', AutoId::UUID); - $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", $query, - 'INSERT statement not constructed correctly'); - $this->assertStringEndsWith("'))", $query, 'INSERT statement not constructed correctly'); - } finally { - Configuration::$mode = null; - } + $query = Query::insert('test_tbl', AutoId::UUID); + $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", $query, + 'INSERT statement not constructed correctly'); + $this->assertStringEndsWith("'))", $query, 'INSERT statement not constructed correctly'); } #[TestDox('Insert succeeds with auto random string for PostgreSQL')] public function testInsertSucceedsWithAutoRandomStringForPostgreSQL(): void { - Configuration::$mode = Mode::PgSQL; + Configuration::overrideMode(Mode::PgSQL); Configuration::$idStringLength = 8; try { $query = Query::insert('test_tbl', AutoId::RandomString); @@ -216,7 +178,6 @@ class QueryTest extends TestCase $id = str_replace(["INSERT INTO test_tbl VALUES (:data::jsonb || '{\"id\":\"", "\"}')"], '', $query); $this->assertEquals(8, strlen($id), "Generated ID [$id] should have been 8 characters long"); } finally { - Configuration::$mode = null; Configuration::$idStringLength = 16; } } @@ -224,23 +185,18 @@ class QueryTest extends TestCase #[TestDox('Insert succeeds with auto random string for SQLite')] public function testInsertSucceedsWithAutoRandomStringForSQLite(): void { - Configuration::$mode = Mode::SQLite; - try { - $query = Query::insert('test_tbl', AutoId::RandomString); - $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", $query, - 'INSERT statement not constructed correctly'); - $this->assertStringEndsWith("'))", $query, 'INSERT statement not constructed correctly'); - $id = str_replace(["INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", "'))"], '', $query); - $this->assertEquals(16, strlen($id), "Generated ID [$id] should have been 16 characters long"); - } finally { - Configuration::$mode = null; - } + $query = Query::insert('test_tbl', AutoId::RandomString); + $this->assertStringStartsWith("INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", $query, + 'INSERT statement not constructed correctly'); + $this->assertStringEndsWith("'))", $query, 'INSERT statement not constructed correctly'); + $id = str_replace(["INSERT INTO test_tbl VALUES (json_set(:data, '$.id', '", "'))"], '', $query); + $this->assertEquals(16, strlen($id), "Generated ID [$id] should have been 16 characters long"); } public function testInsertFailsWhenModeNotSet(): void { $this->expectException(DocumentException::class); - Configuration::$mode = null; + Configuration::overrideMode(null); Query::insert('kaboom'); }