diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa84933..6a4386c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [ 8.1, 8.2 ] + php: [ 8.2, 8.3 ] steps: - uses: actions/checkout@v3 @@ -37,7 +37,7 @@ jobs: needs: [ composer ] strategy: matrix: - php: [ 8.1, 8.2 ] + php: [ 8.2, 8.3 ] outputs: coverage: ${{ steps.store-coverage.outputs.coverage_text }} @@ -90,7 +90,7 @@ jobs: needs: [ composer ] strategy: matrix: - php: [ 8.1, 8.2 ] + php: [ 8.2, 8.3 ] steps: - uses: actions/download-artifact@v3 @@ -112,7 +112,7 @@ jobs: needs: [ composer ] strategy: matrix: - php: [ 8.1, 8.2 ] + php: [ 8.2, 8.3 ] steps: - uses: actions/download-artifact@v3 @@ -136,7 +136,7 @@ jobs: needs: [ composer ] strategy: matrix: - php: [ 8.1, 8.2 ] + php: [ 8.2, 8.3 ] steps: - uses: actions/download-artifact@v3 diff --git a/phpunit.xml b/phpunit.xml index 5e1b5d9..7208740 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -5,6 +5,10 @@ colors="true" cacheDirectory="test/phpunit/.phpunit.cache" bootstrap="vendor/autoload.php" + displayDetailsOnTestsThatTriggerWarnings="true" + displayDetailsOnTestsThatTriggerDeprecations="true" + displayDetailsOnTestsThatTriggerErrors="true" + displayDetailsOnTestsThatTriggerNotices="true" > diff --git a/src/Connection/Driver.php b/src/Connection/Driver.php index d59f00a..e7665ec 100644 --- a/src/Connection/Driver.php +++ b/src/Connection/Driver.php @@ -45,11 +45,12 @@ protected function connect():void { Connection::ATTR_ERRMODE => Connection::ERRMODE_EXCEPTION, ]; - if($this->settings->getSchema() === Settings::DRIVER_MYSQL) { + if($this->settings->getDriver() === Settings::DRIVER_MYSQL) { $options[Connection::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION collation_connection='" . $this->settings->getCollation() . "'"; + $options[Connection::MYSQL_ATTR_LOCAL_INFILE] = true; } $this->connection = new Connection( diff --git a/src/Query/SqlQuery.php b/src/Query/SqlQuery.php index e950da5..87ed8f6 100644 --- a/src/Query/SqlQuery.php +++ b/src/Query/SqlQuery.php @@ -12,10 +12,9 @@ /** @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class SqlQuery extends Query { const SPECIAL_BINDINGS = [ - "limit", - "offset", - "groupBy", - "orderBy", + "field" => ["groupBy", "orderBy"], + "int" => ["limit", "offset"], + "string" => ["infileName"], ]; /** @param array|array $bindings */ @@ -72,8 +71,8 @@ public function execute(array $bindings = []):ResultSet { } catch(PDOException $exception) { throw new PreparedStatementException( - $exception->getMessage(), - $exception->getCode(), + $exception->getMessage() . " (" . $exception->getCode(), + 0, $exception ); } @@ -108,24 +107,37 @@ public function injectSpecialBindings( string $sql, array $bindings ):string { - foreach(self::SPECIAL_BINDINGS as $special) { - $specialPlaceholder = ":" . $special; + foreach(self::SPECIAL_BINDINGS as $type => $specialList) { + foreach($specialList as $special) { + $specialPlaceholder = ":" . $special; - if(!array_key_exists($special, $bindings)) { - continue; - } + if(!array_key_exists($special, $bindings)) { + continue; + } - $replacement = $this->escapeSpecialBinding( - $bindings[$special], - $special - ); + if($type !== "string") { + $replacement = $this->escapeSpecialBinding( + $bindings[$special], + $special + ); + } - $sql = str_replace( - $specialPlaceholder, - $replacement, - $sql - ); - unset($bindings[$special]); + if($type === "field") { + $words = explode(" ", $bindings[$special]); + $words[0] = "`" . $words[0] . "`"; + $replacement = implode(" ", $words); + } + elseif($type === "string") { + $replacement = "'" . $bindings[$special] . "'"; + } + + $sql = str_replace( + $specialPlaceholder, + $replacement, + $sql + ); + unset($bindings[$special]); + } } foreach($bindings as $key => $value) { diff --git a/test/phpunit/Connection/DefaultSettingsTest.php b/test/phpunit/Connection/DefaultSettingsTest.php index 7c8919b..e258eef 100644 --- a/test/phpunit/Connection/DefaultSettingsTest.php +++ b/test/phpunit/Connection/DefaultSettingsTest.php @@ -91,7 +91,7 @@ public function testGetDefaultCharset() { self::assertEquals(DefaultSettings::DEFAULT_COLLATION, $settings->getCollation()); } - public function getDrivers():array { + public static function getDrivers():array { return [ [Settings::DRIVER_MYSQL, 3306], [Settings::DRIVER_POSTGRES, 5432], @@ -99,4 +99,4 @@ public function getDrivers():array { [Settings::DRIVER_SQLITE, 0], ]; } -} \ No newline at end of file +} diff --git a/test/phpunit/Helper/Helper.php b/test/phpunit/Helper/Helper.php index 060afd6..6521d76 100644 --- a/test/phpunit/Helper/Helper.php +++ b/test/phpunit/Helper/Helper.php @@ -82,7 +82,7 @@ private static function queryPathProvider(bool $exists, $extension = "sql") { return $data; } - public function queryPathNestedProvider() { + public static function queryPathNestedProvider() { $data = []; $n = rand(2, 6); @@ -163,4 +163,4 @@ private static function queryCollectionPathProvider( return $data; } -} \ No newline at end of file +} diff --git a/test/phpunit/Migration/MigratorTest.php b/test/phpunit/Migration/MigratorTest.php index d0280d6..0619b74 100644 --- a/test/phpunit/Migration/MigratorTest.php +++ b/test/phpunit/Migration/MigratorTest.php @@ -108,7 +108,7 @@ public function testCheckFileListOrder(array $fileList) { /** @dataProvider dataMigrationFileListMissing */ public function testCheckFileListOrderMissing(array $fileList) { - $path = $this->getMigrationDirectory(); + $path = self::getMigrationDirectory(); $this->createFiles($fileList, $path); $settings = $this->createSettings($path); @@ -542,15 +542,15 @@ public function testMigrationErrorOutputToStream(array $fileList) { } } - public function dataMigrationFileList():array { - $fileList = $this->generateFileList(); + public static function dataMigrationFileList():array { + $fileList = self::generateFileList(); return [ [$fileList] ]; } - public function dataMigrationFileListMissing():array { - $fileList = $this->generateFileList( + public static function dataMigrationFileListMissing():array { + $fileList = self::generateFileList( true, false ); @@ -559,8 +559,8 @@ public function dataMigrationFileListMissing():array { ]; } - public function dataMigrationFileListDuplicate():array { - $fileList = $this->generateFileList( + public static function dataMigrationFileListDuplicate():array { + $fileList = self::generateFileList( false, true ); @@ -638,7 +638,7 @@ protected function hashMigrationToDb( } } - private function generateFileList($missingFiles = false, $duplicateFiles = false) { + private static function generateFileList($missingFiles = false, $duplicateFiles = false) { $fileList = []; $migLength = rand(10, 30); diff --git a/test/phpunit/Query/SqlQueryTest.php b/test/phpunit/Query/SqlQueryTest.php index 648741b..f9d3bcd 100644 --- a/test/phpunit/Query/SqlQueryTest.php +++ b/test/phpunit/Query/SqlQueryTest.php @@ -238,7 +238,7 @@ public function testSpecialBindingsNoAscDesc( self::assertStringNotContainsString(":limit", $injectedSql); self::assertStringNotContainsString(":offset", $injectedSql); - self::assertStringContainsString("order by sortColumn", $injectedSql); + self::assertStringContainsString("order by `sortColumn`", $injectedSql); self::assertStringContainsString("limit 100", $injectedSql); self::assertStringContainsString("offset 25", $injectedSql); } @@ -260,7 +260,7 @@ public function testSpecialBindingsAscDesc( "offset" => 25, ]); - self::assertStringContainsString("order by sortColumn desc", $injectedSql); + self::assertStringContainsString("order by `sortColumn` desc", $injectedSql); } /** diff --git a/test/phpunit/Result/RowTest.php b/test/phpunit/Result/RowTest.php index f3df193..6edb409 100644 --- a/test/phpunit/Result/RowTest.php +++ b/test/phpunit/Result/RowTest.php @@ -123,7 +123,7 @@ public function testGetIntNullable() { self::assertNull($row->getInt("does_not_exist")); } - public function data_getTestRow():array { + public static function data_getTestRow():array { $data = []; $columns = ["id", "name", "example", "exampleFloat", "exampleDateTime", "exampleBool"];