Skip to content

Commit 467c6fc

Browse files
justusmoronid-s-codappix
authored andcommitted
Use public API instead of @internal
We wrap the foreign APIs in our own classes to ease maintenance. The new classes will now use public APIs only, to prevent broken state in minor updates and properly follow semantic versioning. Resolves: #20
1 parent 65e0684 commit 467c6fc

7 files changed

Lines changed: 173 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## v2.0.0 - 2025-10-20
44

5+
### Added
6+
7+
- Support for TYPO3 13.4.19.
8+
They modified `@internal` API and it is the fault of this package to use the API.
9+
We therefore now move to low level public API of doctrine/dbal instead of TYPO3 internal API.
10+
We also encapsulate the access to those APIs for easier maintenance.
11+
512
### BREAKING
613

714
- Remove support for older dependencies.

Classes/Connection.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright (C) 2025 Daniel Siepmann <coding@daniel-siepmann.de>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* as published by the Free Software Foundation; either version 2
11+
* of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21+
* 02110-1301, USA.
22+
*/
23+
24+
namespace Codappix\Typo3PhpDatasets;
25+
26+
use TYPO3\CMS\Core\Database\Connection as Typo3Connection;
27+
28+
/**
29+
* @internal
30+
*/
31+
final readonly class Connection
32+
{
33+
public function __construct(
34+
private Typo3Connection $typo3Connection,
35+
) {
36+
}
37+
38+
public function insert(string $tableName, array $record, array $types): void
39+
{
40+
$this->typo3Connection->insert($tableName, $record, $types);
41+
}
42+
43+
public function getTable(string $tableName): Table
44+
{
45+
foreach ($this->typo3Connection->createSchemaManager()->listTables() as $table) {
46+
if ($table->getObjectName()->toString() === $tableName) {
47+
return new Table($table);
48+
}
49+
}
50+
51+
throw new \RuntimeException('Could not fetch table details for table: ' . $tableName, 1760939710);
52+
}
53+
}

Classes/ConnectionFactory.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright (C) 2025 Daniel Siepmann <coding@daniel-siepmann.de>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* as published by the Free Software Foundation; either version 2
11+
* of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21+
* 02110-1301, USA.
22+
*/
23+
24+
namespace Codappix\Typo3PhpDatasets;
25+
26+
use TYPO3\CMS\Core\Database\ConnectionPool;
27+
use TYPO3\CMS\Core\Utility\GeneralUtility;
28+
29+
final readonly class ConnectionFactory
30+
{
31+
public function createForTable(string $tableName): Connection
32+
{
33+
return new Connection(
34+
GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName)
35+
);
36+
}
37+
}

Classes/PhpDataSet.php

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,32 @@
2323

2424
namespace Codappix\Typo3PhpDatasets;
2525

26+
use Doctrine\DBAL\Schema\Exception\ColumnDoesNotExist;
27+
use Exception;
2628
use RuntimeException;
2729
use TYPO3\CMS\Core\Database\ConnectionPool;
2830
use TYPO3\CMS\Core\Utility\GeneralUtility;
2931

32+
/**
33+
* @api
34+
*/
3035
class PhpDataSet
3136
{
37+
/**
38+
* @api
39+
*/
3240
public function import(array $dataSet): void
3341
{
34-
foreach ($dataSet as $tableName => $records) {
35-
$connection = $this->getConnectionPool()->getConnectionForTable($tableName);
36-
37-
if (method_exists($connection, 'getSchemaManager')) {
38-
// <= 12
39-
$tableDetails = $connection->getSchemaManager()->listTableDetails($tableName);
40-
} elseif (method_exists($connection, 'getSchemaInformation')) {
41-
// >= 13
42-
$tableDetails = $connection->getSchemaInformation()->introspectTable($tableName);
43-
} else {
44-
throw new RuntimeException('Could not check the schema for table: ' . $tableName, 1707144020);
45-
}
42+
$connectionFactory = new ConnectionFactory();
4643

47-
foreach ($records as $record) {
48-
$types = [];
49-
foreach (array_keys($record) as $columnName) {
50-
$types[] = $tableDetails->getColumn((string)$columnName)->getType()->getBindingType();
51-
}
44+
foreach ($dataSet as $tableName => $records) {
45+
$connection = $connectionFactory->createForTable($tableName);
46+
$table = $connection->getTable($tableName);
5247

48+
foreach ($records as $index => $record) {
49+
$types = array_map($table->getTypeForColumn(...), array_keys($record));
5350
$connection->insert($tableName, $record, $types);
5451
}
5552
}
5653
}
57-
58-
private function getConnectionPool(): ConnectionPool
59-
{
60-
return GeneralUtility::makeInstance(ConnectionPool::class);
61-
}
6254
}

Classes/Table.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* Copyright (C) 2025 Daniel Siepmann <coding@daniel-siepmann.de>
7+
*
8+
* This program is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU General Public License
10+
* as published by the Free Software Foundation; either version 2
11+
* of the License, or (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program; if not, write to the Free Software
20+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21+
* 02110-1301, USA.
22+
*/
23+
24+
namespace Codappix\Typo3PhpDatasets;
25+
26+
use Doctrine\DBAL\ParameterType;
27+
use Doctrine\DBAL\Schema\Exception\ColumnDoesNotExist;
28+
use Doctrine\DBAL\Schema\Table as DbalTable;
29+
30+
/**
31+
* @internal
32+
*/
33+
final readonly class Table
34+
{
35+
public function __construct(
36+
private DbalTable $dbalTable,
37+
) {
38+
}
39+
40+
public function getTypeForColumn(string $columnName): ParameterType
41+
{
42+
try {
43+
return $this->dbalTable
44+
->getColumn((string)$columnName)
45+
->getType()
46+
->getBindingType()
47+
;
48+
} catch (ColumnDoesNotExist $e) {
49+
throw new \RuntimeException(sprintf(
50+
'Column "%s" does not exist in table: %s',
51+
$columnName,
52+
$this->dbalTable->getName(),
53+
), 1760941225);
54+
}
55+
}
56+
}

Classes/TestingFramework.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@
2727
use InvalidArgumentException;
2828

2929
/**
30-
* Only use this within an FunctionalTestCase.
30+
* @api
3131
*/
3232
trait TestingFramework
3333
{
34+
/**
35+
* @api
36+
*/
3437
protected function importPHPDataSet(string $filePath): void
3538
{
3639
$this->ensureFileExists($filePath);
@@ -45,6 +48,7 @@ protected function importPHPDataSet(string $filePath): void
4548

4649
/**
4750
* Highly inspired by TYPO3 testing framework.
51+
* @api
4852
*/
4953
protected function assertPHPDataSet(string $filePath): void
5054
{

Tests/Functional/ImportTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function failsIfSqlError(): void
7777
$this->expectExceptionMessageMatches(
7878
'#Error for PHP data-set "' . __DIR__ . '/Fixtures/WithBrokenSql.php":'
7979
. PHP_EOL
80-
. 'There is no column with name .*none_existing_column.* on table .*pages.*\.#'
80+
. 'Column "none_existing_column" does not exist in table: pages#'
8181
);
8282
$this->importPHPDataSet(__DIR__ . '/Fixtures/WithBrokenSql.php');
8383
}

0 commit comments

Comments
 (0)