[!!!][TASK] Drop ext:typo3db_legacy 12/52612/5
authorChristian Kuhn <lolli@schwarzbu.ch>
Wed, 26 Apr 2017 13:17:01 +0000 (15:17 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sat, 3 Jun 2017 20:19:08 +0000 (22:19 +0200)
The extension containing legacy $GLOBALS['TYPO3_DB'] has been moved to
github at https://github.com/FriendsOfTYPO3/typo3db_legacy
and is available as TER extension and now dropped from core.
An upgrade wizard is added to dowload and install the extension
if needed.

Change-Id: Id99794844e39632a3451e19c7a7d55d47bc3118c
Resolves: #81023
Releases: master
Reviewed-on: https://review.typo3.org/52612
Reviewed-by: Johannes Goslar <jogo@kronberger-spiele.de>
Tested-by: Johannes Goslar <jogo@kronberger-spiele.de>
Reviewed-by: Markus Sommer <markussom@posteo.de>
Tested-by: Markus Sommer <markussom@posteo.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: TYPO3com <no-reply@typo3.com>
18 files changed:
composer.json
typo3/sysext/core/Documentation/Changelog/master/Important-81023-DropTypo3db_legacy.rst [new file with mode: 0644]
typo3/sysext/install/Classes/Updates/Typo3DbExtractionUpdate.php [new file with mode: 0644]
typo3/sysext/install/ext_localconf.php
typo3/sysext/typo3db_legacy/Classes/Database/DatabaseConnection.php [deleted file]
typo3/sysext/typo3db_legacy/Classes/Database/PostProcessQueryHookInterface.php [deleted file]
typo3/sysext/typo3db_legacy/Classes/Database/PreProcessQueryHookInterface.php [deleted file]
typo3/sysext/typo3db_legacy/Classes/Database/PreparedStatement.php [deleted file]
typo3/sysext/typo3db_legacy/Classes/Updates/DbalAndAdodbExtractionUpdate.php [deleted file]
typo3/sysext/typo3db_legacy/Migrations/Code/ClassAliasMap.php [deleted file]
typo3/sysext/typo3db_legacy/Resources/Public/Icons/Extension.png [deleted file]
typo3/sysext/typo3db_legacy/Tests/Functional/Database/DatabaseConnectionTest.php [deleted file]
typo3/sysext/typo3db_legacy/Tests/Functional/Database/PreparedStatementTest.php [deleted file]
typo3/sysext/typo3db_legacy/Tests/Unit/Database/DatabaseConnectionTest.php [deleted file]
typo3/sysext/typo3db_legacy/Tests/Unit/Database/PreparedStatementTest.php [deleted file]
typo3/sysext/typo3db_legacy/composer.json [deleted file]
typo3/sysext/typo3db_legacy/ext_emconf.php [deleted file]
typo3/sysext/typo3db_legacy/ext_localconf.php [deleted file]

index e102459..afe2142 100644 (file)
                        "TYPO3\\CMS\\T3editor\\": "typo3/sysext/t3editor/Classes/",
                        "TYPO3\\CMS\\Taskcenter\\": "typo3/sysext/taskcenter/Classes/",
                        "TYPO3\\CMS\\Tstemplate\\": "typo3/sysext/tstemplate/Classes/",
-                       "TYPO3\\CMS\\Typo3DbLegacy\\": "typo3/sysext/typo3db_legacy/Classes/",
                        "TYPO3\\CMS\\Version\\": "typo3/sysext/version/Classes/",
                        "TYPO3\\CMS\\Viewpage\\": "typo3/sysext/viewpage/Classes/",
                        "TYPO3\\CMS\\WizardCrpages\\": "typo3/sysext/wizard_crpages/Classes/",
                        "TYPO3\\CMS\\Sv\\Tests\\": "typo3/sysext/sv/Tests/",
                        "TYPO3\\CMS\\SysAction\\Tests\\": "typo3/sysext/sys_action/Tests/",
                        "TYPO3\\CMS\\SysNote\\Tests\\": "typo3/sysext/sys_note/Tests/",
-                       "TYPO3\\CMS\\Typo3DbLegacy\\Tests\\": "typo3/sysext/typo3db_legacy/Tests/",
                        "TYPO3\\CMS\\Workspaces\\Tests\\": "typo3/sysext/workspaces/Tests/",
                        "TYPO3\\CMS\\Recycler\\Tests\\": "typo3/sysext/recycler/Tests/"
                },
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Important-81023-DropTypo3db_legacy.rst b/typo3/sysext/core/Documentation/Changelog/master/Important-81023-DropTypo3db_legacy.rst
new file mode 100644 (file)
index 0000000..a5b4493
--- /dev/null
@@ -0,0 +1,45 @@
+.. include:: ../../Includes.txt
+
+===========================================
+Important: #81023 - Drop EXT:typo3db_legacy
+===========================================
+
+See :issue:`81023`
+
+Description
+===========
+
+The legacy extension :php:`typo3db_legacy` that contains the old non doctrine based
+database API known as :php:`$GLOBALS['TYPO3_DB']` has been dropped from core.
+
+The extension is available in the TER and an install tool upgrade wizard is in place
+to download and load the extension as compatibility layer for extension that still
+rely on :php:`$GLOBALS['TYPO3_DB']` in TYPO3 v9.
+
+If an extension should be compatible with both TYPO3 v8 and TYPO3 v9 and relies in v9 on typo3db_legacy, it should
+list typo3db_legacy as 'suggests' dependency in it's ext_emconf.php file. This way, the dependency is optional
+and needs to be manually loaded by an administrator in the TYPO3 v9 backend, but the core still ensures
+typo3db_legacy is loaded before the affected extension:
+
+.. code-block:: php
+
+    'constraints' => [
+        ...
+        'suggests' => [
+            'typo3db_legacy' => '1.0.0-1.0.99',
+        ],
+    ],
+
+Extensions that dropped support for TYPO3 v8 (or keeps separate branches) and did not migrate to doctrine in
+its v9 version, should list typo3db_legacy in the 'depends' section of ext_emconf.php:
+
+.. code-block:: php
+
+    'constraints' => [
+        ...
+        'depends' => [
+            'typo3db_legacy' => '1.0.0-1.0.99',
+        ],
+    ],
+
+.. index:: Database, PHP-API
\ No newline at end of file
diff --git a/typo3/sysext/install/Classes/Updates/Typo3DbExtractionUpdate.php b/typo3/sysext/install/Classes/Updates/Typo3DbExtractionUpdate.php
new file mode 100644 (file)
index 0000000..64ef559
--- /dev/null
@@ -0,0 +1,123 @@
+<?php
+namespace TYPO3\CMS\Install\Updates;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Installs and downloads EXT:typo3db_legacy
+ */
+class Typo3DbExtractionUpdate extends AbstractDownloadExtensionUpdate
+{
+    /**
+     * @var string
+     */
+    protected $title = 'Install extension "typo3db_legacy" from TER';
+
+    /**
+     * @var string
+     */
+    protected $extensionKey = 'typo3db_legacy';
+
+    /**
+     * @var array
+     */
+    protected $extensionDetails = [
+        'typo3db_legacy' => [
+            'title' => '$GLOBALS[\'TYPO3_DB\'] compatibility layer',
+            'description' => 'Provides the well-known database API $GLOBALS[\'TYPO3_DB\'] used in previous TYPO3 versions for extensions that still rely on it.',
+            'versionString' => '1.0.1',
+        ]
+    ];
+
+    /**
+     * Checks if an update is needed
+     *
+     * @param string $description The description for the update
+     * @return bool Whether an update is needed (true) or not (false)
+     */
+    public function checkForUpdate(&$description)
+    {
+        $description = 'The old database API populated as $GLOBALS[\'TYPO3_DB\'] has been extracted into'
+            . ' the TYPO3 Extension Repository. This update downloads the TYPO3 extension typo3db_legacy from the TER.'
+            . ' Use this if you\'re dealing with extensions in the instance that still rely on the old database API.';
+
+        $updateNeeded = false;
+
+        if (!$this->isWizardDone()) {
+            $updateNeeded = true;
+        }
+
+        return $updateNeeded;
+    }
+
+    /**
+     * Second step: Ask user to install the extension
+     *
+     * @param string $inputPrefix input prefix, all names of form fields have to start with this. Append custom name in [ ... ]
+     * @return string HTML output
+     */
+    public function getUserInput($inputPrefix)
+    {
+        return '
+            <div class="panel panel-danger">
+                <div class="panel-heading">Are you really sure?</div>
+                <div class="panel-body">
+                    <p>You should install EXT:typo3db_legacy only if you really need it.</p>
+                    <p>This update wizard cannot check if the extension was installed before the update.</p>
+                    <p>Are you really sure, you want to install EXT:typo3db_legacy?</p>
+                    <div class="btn-group clearfix" data-toggle="buttons">
+                        <label class="btn btn-default active">
+                            <input type="radio" name="' . $inputPrefix . '[install]" value="0" checked="checked" /> no, don\'t install
+                        </label>
+                        <label class="btn btn-default">
+                            <input type="radio" name="' . $inputPrefix . '[install]" value="1" /> yes, please install
+                        </label>
+                    </div>
+                </div>
+            </div>
+        ';
+    }
+
+    /**
+     * Performs the update if EXT:typo3db_legacy should be installed.
+     *
+     * @param array $databaseQueries Queries done in this update
+     * @param string $customMessage Custom message
+     * @return bool
+     */
+    public function performUpdate(array &$databaseQueries, &$customMessage)
+    {
+        $requestParams = GeneralUtility::_GP('install');
+        if (!isset($requestParams['values']['typo3DbLegacyExtension']['install'])) {
+            return false;
+        }
+        $install = (int)$requestParams['values']['typo3DbLegacyExtension']['install'];
+
+        if ($install === 1) {
+            // user decided to install extension, install and mark wizard as done
+            $updateSuccessful = $this->installExtension($this->extensionKey, $customMessage);
+            if ($updateSuccessful) {
+                $this->markWizardAsDone();
+                return true;
+            }
+        } else {
+            // user decided to not install extension, mark wizard as done
+            $this->markWizardAsDone();
+            return true;
+        }
+        return $updateSuccessful;
+    }
+}
index 816ce89..850cab8 100644 (file)
@@ -53,3 +53,5 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['rtehtmlareaE
     = \TYPO3\CMS\Install\Updates\RteHtmlAreaExtractionUpdate::class;
 
 // Add update wizards below this line
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['typo3DbLegacyExtension']
+    = \TYPO3\CMS\Install\Updates\Typo3DbExtractionUpdate::class;
diff --git a/typo3/sysext/typo3db_legacy/Classes/Database/DatabaseConnection.php b/typo3/sysext/typo3db_legacy/Classes/Database/DatabaseConnection.php
deleted file mode 100644 (file)
index a5207e8..0000000
+++ /dev/null
@@ -1,2022 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Database\Connection;
-use TYPO3\CMS\Core\Database\Query\QueryHelper;
-use TYPO3\CMS\Core\TimeTracker\TimeTracker;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\StringUtility;
-
-/**
- * @deprecated  ------------- THE WHOLE CLASS WILL BE REMOVED IN TYPO3 v9 ----------------------------------------------
- * DatabaseConnection a.k.a. TYPO3_DB has been superseded by Doctrine DBAL in TYPO3 v8, and will be removed in TYPO3 v9
- * ---------------------------------------------------------------------------------------------------------------------
- * Contains the class "DatabaseConnection" containing functions for building SQL queries
- * and mysqli wrappers, thus providing a foundational API to all database
- * interaction.
- * This class is instantiated globally as $TYPO3_DB in TYPO3 scripts.
- *
- * TYPO3 "database wrapper" class (new in 3.6.0)
- * This class contains
- * - abstraction functions for executing INSERT/UPDATE/DELETE/SELECT queries ("Query execution"; These are REQUIRED for all future connectivity to the database, thus ensuring DBAL compliance!)
- * - functions for building SQL queries (INSERT/UPDATE/DELETE/SELECT) ("Query building"); These are transitional functions for building SQL queries in a more automated way. Use these to build queries instead of doing it manually in your code!
- * - mysqli wrapper functions; These are transitional functions. By a simple search/replace you should be able to substitute all mysql*() calls with $GLOBALS['TYPO3_DB']->sql*() and your application will work out of the box. YOU CANNOT (legally) use any mysqli functions not found as wrapper functions in this class!
- * See the Project Coding Guidelines (doc_core_cgl) for more instructions on best-practise
- *
- * This class is not in itself a complete database abstraction layer but can be extended to be a DBAL (by extensions, see "dbal" for example)
- * ALL connectivity to the database in TYPO3 must be done through this class!
- * The points of this class are:
- * - To direct all database calls through this class so it becomes possible to implement DBAL with extensions.
- * - To keep it very easy to use for developers used to MySQL in PHP - and preserve as much performance as possible when TYPO3 is used with MySQL directly...
- * - To create an interface for DBAL implemented by extensions; (Eg. making possible escaping characters, clob/blob handling, reserved words handling)
- * - Benchmarking the DB bottleneck queries will become much easier; Will make it easier to find optimization possibilities.
- *
- * USE:
- * In all TYPO3 scripts the global variable $TYPO3_DB is an instance of this class. Use that.
- * Eg. $GLOBALS['TYPO3_DB']->sql_fetch_assoc()
- */
-class DatabaseConnection
-{
-    /**
-     * The AND constraint in where clause
-     *
-     * @var string
-     */
-    const AND_Constraint = 'AND';
-
-    /**
-     * The OR constraint in where clause
-     *
-     * @var string
-     */
-    const OR_Constraint = 'OR';
-
-    /**
-     * Set "TRUE" or "1" if you want database errors outputted. Set to "2" if you also want successful database actions outputted.
-     *
-     * @var bool|int
-     */
-    public $debugOutput = false;
-
-    /**
-     * Internally: Set to last built query (not necessarily executed...)
-     *
-     * @var string
-     */
-    public $debug_lastBuiltQuery = '';
-
-    /**
-     * Set "TRUE" if you want the last built query to be stored in $debug_lastBuiltQuery independent of $this->debugOutput
-     *
-     * @var bool
-     */
-    public $store_lastBuiltQuery = false;
-
-    /**
-     * Set this to 1 to get queries explained (devIPmask must match). Set the value to 2 to the same but disregarding the devIPmask.
-     * There is an alternative option to enable explain output in the admin panel under "TypoScript", which will produce much nicer output, but only works in FE.
-     *
-     * @var bool
-     */
-    public $explainOutput = 0;
-
-    /**
-     * @var string Database host to connect to
-     */
-    protected $databaseHost = '';
-
-    /**
-     * @var int Database port to connect to
-     */
-    protected $databasePort = 3306;
-
-    /**
-     * @var string|NULL Database socket to connect to
-     */
-    protected $databaseSocket = null;
-
-    /**
-     * @var string Database name to connect to
-     */
-    protected $databaseName = '';
-
-    /**
-     * @var string Database user to connect with
-     */
-    protected $databaseUsername = '';
-
-    /**
-     * @var string Database password to connect with
-     */
-    protected $databaseUserPassword = '';
-
-    /**
-     * @var bool TRUE if database connection should be persistent
-     * @see http://php.net/manual/de/mysqli.persistconns.php
-     */
-    protected $persistentDatabaseConnection = false;
-
-    /**
-     * @var bool TRUE if connection between client and sql server is compressed
-     */
-    protected $connectionCompression = false;
-
-    /**
-     * The charset for the connection; will be passed on to
-     * mysqli_set_charset during connection initialization.
-     *
-     * @var string
-     */
-    protected $connectionCharset = 'utf8';
-
-    /**
-     * @var array List of commands executed after connection was established
-     */
-    protected $initializeCommandsAfterConnect = [];
-
-    /**
-     * @var bool TRUE if database connection is established
-     */
-    protected $isConnected = false;
-
-    /**
-     * @var \mysqli $link Default database link object
-     */
-    protected $link = null;
-
-    /**
-     * Default character set, applies unless character set or collation are explicitly set
-     *
-     * @var string
-     */
-    public $default_charset = 'utf8';
-
-    /**
-     * @var array<PostProcessQueryHookInterface>
-     */
-    protected $preProcessHookObjects = [];
-
-    /**
-     * @var array<PreProcessQueryHookInterface>
-     */
-    protected $postProcessHookObjects = [];
-
-    /**
-     * Internal property to mark if a deprecation log warning has been thrown in this request
-     * in order to avoid a load of deprecation.
-     * @var bool
-     */
-    protected $deprecationWarningThrown = false;
-
-    /**
-     * Initialize the database connection
-     */
-    public function initialize()
-    {
-        // Intentionally blank as this will be overloaded by DBAL
-    }
-
-    /************************************
-     *
-     * Query execution
-     *
-     * These functions are the RECOMMENDED DBAL functions for use in your applications
-     * Using these functions will allow the DBAL to use alternative ways of accessing data (contrary to if a query is returned!)
-     * They compile a query AND execute it immediately and then return the result
-     * This principle heightens our ability to create various forms of DBAL of the functions.
-     * Generally: We want to return a result pointer/object, never queries.
-     * Also, having the table name together with the actual query execution allows us to direct the request to other databases.
-     *
-     **************************************/
-
-    /**
-     * Creates and executes an INSERT SQL-statement for $table from the array with field/value pairs $fields_values.
-     * Using this function specifically allows us to handle BLOB and CLOB fields depending on DB
-     *
-     * @param string $table Table name
-     * @param array $fields_values Field values as key=>value pairs. Values will be escaped internally. Typically you would fill an array like "$insertFields" with 'fieldname'=>'value' and pass it to this function as argument.
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function exec_INSERTquery($table, $fields_values, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        $res = $this->query($this->INSERTquery($table, $fields_values, $no_quote_fields));
-        if ($this->debugOutput) {
-            $this->debug('exec_INSERTquery');
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_INSERTquery_postProcessAction($table, $fields_values, $no_quote_fields, $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Creates and executes an INSERT SQL-statement for $table with multiple rows.
-     *
-     * @param string $table Table name
-     * @param array $fields Field names
-     * @param array $rows Table rows. Each row should be an array with field values mapping to $fields
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function exec_INSERTmultipleRows($table, array $fields, array $rows, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        $res = $this->query($this->INSERTmultipleRows($table, $fields, $rows, $no_quote_fields));
-        if ($this->debugOutput) {
-            $this->debug('exec_INSERTmultipleRows');
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_INSERTmultipleRows_postProcessAction($table, $fields, $rows, $no_quote_fields, $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Creates and executes an UPDATE SQL-statement for $table where $where-clause (typ. 'uid=...') from the array with field/value pairs $fields_values.
-     * Using this function specifically allow us to handle BLOB and CLOB fields depending on DB
-     *
-     * @param string $table Database tablename
-     * @param string $where WHERE clause, eg. "uid=1". NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself!
-     * @param array $fields_values Field values as key=>value pairs. Values will be escaped internally. Typically you would fill an array like "$updateFields" with 'fieldname'=>'value' and pass it to this function as argument.
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function exec_UPDATEquery($table, $where, $fields_values, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        $res = $this->query($this->UPDATEquery($table, $where, $fields_values, $no_quote_fields));
-        if ($this->debugOutput) {
-            $this->debug('exec_UPDATEquery');
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_UPDATEquery_postProcessAction($table, $where, $fields_values, $no_quote_fields, $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Creates and executes a DELETE SQL-statement for $table where $where-clause
-     *
-     * @param string $table Database tablename
-     * @param string $where WHERE clause, eg. "uid=1". NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself!
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function exec_DELETEquery($table, $where)
-    {
-        $this->logDeprecation();
-        $res = $this->query($this->DELETEquery($table, $where));
-        if ($this->debugOutput) {
-            $this->debug('exec_DELETEquery');
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_DELETEquery_postProcessAction($table, $where, $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Creates and executes a SELECT SQL-statement
-     * Using this function specifically allow us to handle the LIMIT feature independently of DB.
-     *
-     * @param string $select_fields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-     * @param string $from_table Table(s) from which to select. This is what comes right after "FROM ...". Required value.
-     * @param string $where_clause Additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
-     * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-     * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-     * @param string $limit Optional LIMIT value ([begin,]max), if none, supply blank string.
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '')
-    {
-        $this->logDeprecation();
-        $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
-        $res = $this->query($query);
-        if ($this->debugOutput) {
-            $this->debug('exec_SELECTquery');
-        }
-        if ($this->explainOutput) {
-            $this->explain($query, $from_table, $res->num_rows);
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_SELECTquery_postProcessAction($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '', $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Creates and executes a SELECT query, selecting fields ($select) from two/three tables joined
-     * Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
-     * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
-     * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $GLOBALS['TCA'] in Inside TYPO3 for more details.
-     *
-     * @param string $select Field list for SELECT
-     * @param string $local_table Tablename, local table
-     * @param string $mm_table Tablename, relation table
-     * @param string $foreign_table Tablename, foreign table
-     * @param string $whereClause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT! You have to prepend 'AND ' to this parameter yourself!
-     * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-     * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-     * @param string $limit Optional LIMIT value ([begin,]max), if none, supply blank string.
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     * @see exec_SELECTquery()
-     */
-    public function exec_SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '')
-    {
-        $this->logDeprecation();
-        $queryParts = $this->getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
-        return $this->exec_SELECT_queryArray($queryParts);
-    }
-
-    /**
-     * Executes a select based on input query parts array
-     *
-     * @param array $queryParts Query parts array
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     * @see exec_SELECTquery()
-     */
-    public function exec_SELECT_queryArray($queryParts)
-    {
-        $this->logDeprecation();
-        return $this->exec_SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT']);
-    }
-
-    /**
-     * Creates and executes a SELECT SQL-statement AND traverse result set and returns array with records in.
-     *
-     * @param string $select_fields List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
-     * @param string $from_table Table(s) from which to select. This is what comes right after "FROM ...". Required value.
-     * @param string $where_clause Additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
-     * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-     * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-     * @param string $limit Optional LIMIT value ([begin,]max), if none, supply blank string.
-     * @param string $uidIndexField If set, the result array will carry this field names value as index. Requires that field to be selected of course!
-     * @return array|NULL Array of rows, or NULL in case of SQL error
-     * @see exec_SELECTquery()
-     * @throws \InvalidArgumentException
-     */
-    public function exec_SELECTgetRows($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '', $uidIndexField = '')
-    {
-        $this->logDeprecation();
-        $res = $this->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
-        if ($this->sql_error()) {
-            $this->sql_free_result($res);
-            return null;
-        }
-        $output = [];
-        $firstRecord = true;
-        while ($record = $this->sql_fetch_assoc($res)) {
-            if ($uidIndexField) {
-                if ($firstRecord) {
-                    $firstRecord = false;
-                    if (!array_key_exists($uidIndexField, $record)) {
-                        $this->sql_free_result($res);
-                        throw new \InvalidArgumentException('The given $uidIndexField "' . $uidIndexField . '" is not available in the result.', 1432933855);
-                    }
-                }
-                $output[$record[$uidIndexField]] = $record;
-            } else {
-                $output[] = $record;
-            }
-        }
-        $this->sql_free_result($res);
-        return $output;
-    }
-
-    /**
-     * Creates and executes a SELECT SQL-statement AND gets a result set and returns an array with a single record in.
-     * LIMIT is automatically set to 1 and can not be overridden.
-     *
-     * @param string $select_fields List of fields to select from the table.
-     * @param string $from_table Table(s) from which to select.
-     * @param string $where_clause Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself!
-     * @param string $groupBy Optional GROUP BY field(s), if none, supply blank string.
-     * @param string $orderBy Optional ORDER BY field(s), if none, supply blank string.
-     * @param bool $numIndex If set, the result will be fetched with sql_fetch_row, otherwise sql_fetch_assoc will be used.
-     * @return array|FALSE|NULL Single row, FALSE on empty result, NULL on error
-     */
-    public function exec_SELECTgetSingleRow($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $numIndex = false)
-    {
-        $this->logDeprecation();
-        $res = $this->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, '1');
-        $output = null;
-        if ($res !== false) {
-            if ($numIndex) {
-                $output = $this->sql_fetch_row($res);
-            } else {
-                $output = $this->sql_fetch_assoc($res);
-            }
-            $this->sql_free_result($res);
-        }
-        return $output;
-    }
-
-    /**
-     * Counts the number of rows in a table.
-     *
-     * @param string $field Name of the field to use in the COUNT() expression (e.g. '*')
-     * @param string $table Name of the table to count rows for
-     * @param string $where (optional) WHERE statement of the query
-     * @return mixed Number of rows counter (int) or FALSE if something went wrong (bool)
-     */
-    public function exec_SELECTcountRows($field, $table, $where = '1=1')
-    {
-        $this->logDeprecation();
-        $count = false;
-        $resultSet = $this->exec_SELECTquery('COUNT(' . $field . ')', $table, $where);
-        if ($resultSet !== false) {
-            list($count) = $this->sql_fetch_row($resultSet);
-            $count = (int)$count;
-            $this->sql_free_result($resultSet);
-        }
-        return $count;
-    }
-
-    /**
-     * Truncates a table.
-     *
-     * @param string $table Database tablename
-     * @return mixed Result from handler
-     */
-    public function exec_TRUNCATEquery($table)
-    {
-        $this->logDeprecation();
-        $res = $this->query($this->TRUNCATEquery($table));
-        if ($this->debugOutput) {
-            $this->debug('exec_TRUNCATEquery');
-        }
-        foreach ($this->postProcessHookObjects as $hookObject) {
-            /** @var $hookObject PostProcessQueryHookInterface */
-            $hookObject->exec_TRUNCATEquery_postProcessAction($table, $this);
-        }
-        return $res;
-    }
-
-    /**
-     * Central query method. Also checks if there is a database connection.
-     * Use this to execute database queries instead of directly calling $this->link->query()
-     *
-     * @param string $query The query to send to the database
-     * @return bool|\mysqli_result
-     */
-    protected function query($query)
-    {
-        $this->logDeprecation();
-        if (!$this->isConnected) {
-            $this->connectDB();
-        }
-        return $this->link->query($query);
-    }
-
-    /**************************************
-     *
-     * Query building
-     *
-     **************************************/
-    /**
-     * Creates an INSERT SQL-statement for $table from the array with field/value pairs $fields_values.
-     *
-     * @param string $table See exec_INSERTquery()
-     * @param array $fields_values See exec_INSERTquery()
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @return string|NULL Full SQL query for INSERT, NULL if $fields_values is empty
-     */
-    public function INSERTquery($table, $fields_values, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        // Table and fieldnames should be "SQL-injection-safe" when supplied to this
-        // function (contrary to values in the arrays which may be insecure).
-        if (!is_array($fields_values) || empty($fields_values)) {
-            return null;
-        }
-        foreach ($this->preProcessHookObjects as $hookObject) {
-            $hookObject->INSERTquery_preProcessAction($table, $fields_values, $no_quote_fields, $this);
-        }
-        // Quote and escape values
-        $fields_values = $this->fullQuoteArray($fields_values, $table, $no_quote_fields, true);
-        // Build query
-        $query = 'INSERT INTO ' . $table . ' (' . implode(',', array_keys($fields_values)) . ') VALUES ' . '(' . implode(',', $fields_values) . ')';
-        // Return query
-        if ($this->debugOutput || $this->store_lastBuiltQuery) {
-            $this->debug_lastBuiltQuery = $query;
-        }
-        return $query;
-    }
-
-    /**
-     * Creates an INSERT SQL-statement for $table with multiple rows.
-     *
-     * @param string $table Table name
-     * @param array $fields Field names
-     * @param array $rows Table rows. Each row should be an array with field values mapping to $fields
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @return string|NULL Full SQL query for INSERT, NULL if $rows is empty
-     */
-    public function INSERTmultipleRows($table, array $fields, array $rows, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        // Table and fieldnames should be "SQL-injection-safe" when supplied to this
-        // function (contrary to values in the arrays which may be insecure).
-        if (empty($rows)) {
-            return null;
-        }
-        foreach ($this->preProcessHookObjects as $hookObject) {
-            /** @var $hookObject PreProcessQueryHookInterface */
-            $hookObject->INSERTmultipleRows_preProcessAction($table, $fields, $rows, $no_quote_fields, $this);
-        }
-        // Build query
-        $query = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES ';
-        $rowSQL = [];
-        foreach ($rows as $row) {
-            // Quote and escape values
-            $row = $this->fullQuoteArray($row, $table, $no_quote_fields);
-            $rowSQL[] = '(' . implode(', ', $row) . ')';
-        }
-        $query .= implode(', ', $rowSQL);
-        // Return query
-        if ($this->debugOutput || $this->store_lastBuiltQuery) {
-            $this->debug_lastBuiltQuery = $query;
-        }
-        return $query;
-    }
-
-    /**
-     * Creates an UPDATE SQL-statement for $table where $where-clause (typ. 'uid=...') from the array with field/value pairs $fields_values.
-     *
-     *
-     * @param string $table See exec_UPDATEquery()
-     * @param string $where See exec_UPDATEquery()
-     * @param array $fields_values See exec_UPDATEquery()
-     * @param bool|array|string $no_quote_fields See fullQuoteArray()
-     * @throws \InvalidArgumentException
-     * @return string Full SQL query for UPDATE
-     */
-    public function UPDATEquery($table, $where, $fields_values, $no_quote_fields = false)
-    {
-        $this->logDeprecation();
-        // Table and fieldnames should be "SQL-injection-safe" when supplied to this
-        // function (contrary to values in the arrays which may be insecure).
-        if (is_string($where)) {
-            foreach ($this->preProcessHookObjects as $hookObject) {
-                /** @var $hookObject PreProcessQueryHookInterface */
-                $hookObject->UPDATEquery_preProcessAction($table, $where, $fields_values, $no_quote_fields, $this);
-            }
-            $fields = [];
-            if (is_array($fields_values) && !empty($fields_values)) {
-                // Quote and escape values
-                $nArr = $this->fullQuoteArray($fields_values, $table, $no_quote_fields, true);
-                foreach ($nArr as $k => $v) {
-                    $fields[] = $k . '=' . $v;
-                }
-            }
-            // Build query
-            $query = 'UPDATE ' . $table . ' SET ' . implode(',', $fields) . ((string)$where !== '' ? ' WHERE ' . $where : '');
-            if ($this->debugOutput || $this->store_lastBuiltQuery) {
-                $this->debug_lastBuiltQuery = $query;
-            }
-            return $query;
-        } else {
-            throw new \InvalidArgumentException('TYPO3 Fatal Error: "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !', 1270853880);
-        }
-    }
-
-    /**
-     * Creates a DELETE SQL-statement for $table where $where-clause
-     *
-     * @param string $table See exec_DELETEquery()
-     * @param string $where See exec_DELETEquery()
-     * @return string Full SQL query for DELETE
-     * @throws \InvalidArgumentException
-     */
-    public function DELETEquery($table, $where)
-    {
-        $this->logDeprecation();
-        if (is_string($where)) {
-            foreach ($this->preProcessHookObjects as $hookObject) {
-                /** @var $hookObject PreProcessQueryHookInterface */
-                $hookObject->DELETEquery_preProcessAction($table, $where, $this);
-            }
-            // Table and fieldnames should be "SQL-injection-safe" when supplied to this function
-            $query = 'DELETE FROM ' . $table . ((string)$where !== '' ? ' WHERE ' . $where : '');
-            if ($this->debugOutput || $this->store_lastBuiltQuery) {
-                $this->debug_lastBuiltQuery = $query;
-            }
-            return $query;
-        } else {
-            throw new \InvalidArgumentException('TYPO3 Fatal Error: "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !', 1270853881);
-        }
-    }
-
-    /**
-     * Creates a SELECT SQL-statement
-     *
-     * @param string $select_fields See exec_SELECTquery()
-     * @param string $from_table See exec_SELECTquery()
-     * @param string $where_clause See exec_SELECTquery()
-     * @param string $groupBy See exec_SELECTquery()
-     * @param string $orderBy See exec_SELECTquery()
-     * @param string $limit See exec_SELECTquery()
-     * @return string Full SQL query for SELECT
-     */
-    public function SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '')
-    {
-        $this->logDeprecation();
-        foreach ($this->preProcessHookObjects as $hookObject) {
-            /** @var $hookObject PreProcessQueryHookInterface */
-            $hookObject->SELECTquery_preProcessAction($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit, $this);
-        }
-        // Table and fieldnames should be "SQL-injection-safe" when supplied to this function
-        // Build basic query
-        $query = 'SELECT ' . $select_fields . ' FROM ' . $from_table . ((string)$where_clause !== '' ? ' WHERE ' . $where_clause : '');
-        // Group by
-        $query .= (string)$groupBy !== '' ? ' GROUP BY ' . $groupBy : '';
-        // Order by
-        $query .= (string)$orderBy !== '' ? ' ORDER BY ' . $orderBy : '';
-        // Group by
-        $query .= (string)$limit !== '' ? ' LIMIT ' . $limit : '';
-        // Return query
-        if ($this->debugOutput || $this->store_lastBuiltQuery) {
-            $this->debug_lastBuiltQuery = $query;
-        }
-        return $query;
-    }
-
-    /**
-     * Creates a SELECT SQL-statement to be used as subquery within another query.
-     * BEWARE: This method should not be overridden within DBAL to prevent quoting from happening.
-     *
-     * @param string $select_fields List of fields to select from the table.
-     * @param string $from_table Table from which to select.
-     * @param string $where_clause Conditional WHERE statement
-     * @return string Full SQL query for SELECT
-     */
-    public function SELECTsubquery($select_fields, $from_table, $where_clause)
-    {
-        $this->logDeprecation();
-        // Table and fieldnames should be "SQL-injection-safe" when supplied to this function
-        // Build basic query:
-        $query = 'SELECT ' . $select_fields . ' FROM ' . $from_table . ((string)$where_clause !== '' ? ' WHERE ' . $where_clause : '');
-        // Return query
-        if ($this->debugOutput || $this->store_lastBuiltQuery) {
-            $this->debug_lastBuiltQuery = $query;
-        }
-        return $query;
-    }
-
-    /**
-     * Creates a SELECT query, selecting fields ($select) from two/three tables joined
-     * Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
-     * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
-     * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $GLOBALS['TCA'] in Inside TYPO3 for more details.
-     *
-     * @param string $select See exec_SELECT_mm_query()
-     * @param string $local_table See exec_SELECT_mm_query()
-     * @param string $mm_table See exec_SELECT_mm_query()
-     * @param string $foreign_table See exec_SELECT_mm_query()
-     * @param string $whereClause See exec_SELECT_mm_query()
-     * @param string $groupBy See exec_SELECT_mm_query()
-     * @param string $orderBy See exec_SELECT_mm_query()
-     * @param string $limit See exec_SELECT_mm_query()
-     * @return string Full SQL query for SELECT
-     * @see SELECTquery()
-     */
-    public function SELECT_mm_query($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '')
-    {
-        $this->logDeprecation();
-        $queryParts = $this->getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause, $groupBy, $orderBy, $limit);
-        return $this->SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT']);
-    }
-
-    /**
-     * Creates a TRUNCATE TABLE SQL-statement
-     *
-     * @param string $table See exec_TRUNCATEquery()
-     * @return string Full SQL query for TRUNCATE TABLE
-     */
-    public function TRUNCATEquery($table)
-    {
-        $this->logDeprecation();
-        foreach ($this->preProcessHookObjects as $hookObject) {
-            /** @var $hookObject PreProcessQueryHookInterface */
-            $hookObject->TRUNCATEquery_preProcessAction($table, $this);
-        }
-        // Table should be "SQL-injection-safe" when supplied to this function
-        // Build basic query:
-        $query = 'TRUNCATE TABLE ' . $table;
-        // Return query:
-        if ($this->debugOutput || $this->store_lastBuiltQuery) {
-            $this->debug_lastBuiltQuery = $query;
-        }
-        return $query;
-    }
-
-    /**
-     * Returns a WHERE clause that can find a value ($value) in a list field ($field)
-     * For instance a record in the database might contain a list of numbers,
-     * "34,234,5" (with no spaces between). This query would be able to select that
-     * record based on the value "34", "234" or "5" regardless of their position in
-     * the list (left, middle or right).
-     * The value must not contain a comma (,)
-     * Is nice to look up list-relations to records or files in TYPO3 database tables.
-     *
-     * @param string $field Field name
-     * @param string $value Value to find in list
-     * @param string $table Table in which we are searching (for DBAL detection of quoteStr() method)
-     * @return string WHERE clause for a query
-     * @throws \InvalidArgumentException
-     */
-    public function listQuery($field, $value, $table)
-    {
-        $this->logDeprecation();
-        $value = (string)$value;
-        if (strpos($value, ',') !== false) {
-            throw new \InvalidArgumentException('$value must not contain a comma (,) in $this->listQuery() !', 1294585862);
-        }
-        $pattern = $this->quoteStr($value, $table);
-        $where = 'FIND_IN_SET(\'' . $pattern . '\',' . $field . ')';
-        return $where;
-    }
-
-    /**
-     * Returns a WHERE clause which will make an AND or OR search for the words in the $searchWords array in any of the fields in array $fields.
-     *
-     * @param array $searchWords Array of search words
-     * @param array $fields Array of fields
-     * @param string $table Table in which we are searching (for DBAL detection of quoteStr() method)
-     * @param string $constraint How multiple search words have to match ('AND' or 'OR')
-     * @return string WHERE clause for search
-     */
-    public function searchQuery($searchWords, $fields, $table, $constraint = self::AND_Constraint)
-    {
-        $this->logDeprecation();
-        switch ($constraint) {
-            case self::OR_Constraint:
-                $constraint = 'OR';
-                break;
-            default:
-                $constraint = 'AND';
-        }
-
-        $queryParts = [];
-        foreach ($searchWords as $sw) {
-            $like = ' LIKE \'%' . $this->quoteStr($this->escapeStrForLike($sw, $table), $table) . '%\'';
-            $queryParts[] = $table . '.' . implode(($like . ' OR ' . $table . '.'), $fields) . $like;
-        }
-        $query = '(' . implode(') ' . $constraint . ' (', $queryParts) . ')';
-
-        return $query;
-    }
-
-    /**************************************
-     *
-     * Prepared Query Support
-     *
-     **************************************/
-    /**
-     * Creates a SELECT prepared SQL statement.
-     *
-     * @param string $select_fields See exec_SELECTquery()
-     * @param string $from_table See exec_SELECTquery()
-     * @param string $where_clause See exec_SELECTquery()
-     * @param string $groupBy See exec_SELECTquery()
-     * @param string $orderBy See exec_SELECTquery()
-     * @param string $limit See exec_SELECTquery()
-     * @param array $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::PARAM_AUTOTYPE.
-     * @return \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement Prepared statement
-     */
-    public function prepare_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '', array $input_parameters = [])
-    {
-        $this->logDeprecation();
-        $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
-        /** @var $preparedStatement \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement */
-        $preparedStatement = GeneralUtility::makeInstance(\TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::class, $query, $from_table, []);
-        // Bind values to parameters
-        foreach ($input_parameters as $key => $value) {
-            $preparedStatement->bindValue($key, $value, PreparedStatement::PARAM_AUTOTYPE);
-        }
-        // Return prepared statement
-        return $preparedStatement;
-    }
-
-    /**
-     * Creates a SELECT prepared SQL statement based on input query parts array
-     *
-     * @param array $queryParts Query parts array
-     * @param array $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::PARAM_AUTOTYPE.
-     * @return \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement Prepared statement
-     */
-    public function prepare_SELECTqueryArray(array $queryParts, array $input_parameters = [])
-    {
-        $this->logDeprecation();
-        return $this->prepare_SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT'], $input_parameters);
-    }
-
-    /**
-     * Prepares a prepared query.
-     *
-     * @param string $query The query to execute
-     * @param array $queryComponents The components of the query to execute
-     * @return \mysqli_stmt|object MySQLi statement / DBAL object
-     * @internal This method may only be called by \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement
-     */
-    public function prepare_PREPAREDquery($query, array $queryComponents)
-    {
-        $this->logDeprecation();
-        if (!$this->isConnected) {
-            $this->connectDB();
-        }
-        $stmt = $this->link->stmt_init();
-        $success = $stmt->prepare($query);
-        if ($this->debugOutput) {
-            $this->debug('stmt_execute', $query);
-        }
-        return $success ? $stmt : null;
-    }
-
-    /**************************************
-     *
-     * Various helper functions
-     *
-     * Functions recommended to be used for
-     * - escaping values,
-     * - cleaning lists of values,
-     * - stripping of excess ORDER BY/GROUP BY keywords
-     *
-     **************************************/
-    /**
-     * Escaping and quoting values for SQL statements.
-     *
-     * @param string $str Input string
-     * @param string $table Table name for which to quote string. Just enter the table that the field-value is selected from (and any DBAL will look up which handler to use and then how to quote the string!).
-     * @param bool $allowNull Whether to allow NULL values
-     * @return string Output string; Wrapped in single quotes and quotes in the string (" / ') and \ will be backslashed (or otherwise based on DBAL handler)
-     * @see quoteStr()
-     */
-    public function fullQuoteStr($str, $table, $allowNull = false)
-    {
-        $this->logDeprecation();
-        if (!$this->isConnected) {
-            $this->connectDB();
-        }
-        if ($allowNull && $str === null) {
-            return 'NULL';
-        }
-        if (is_bool($str)) {
-            $str = (int)$str;
-        }
-
-        return '\'' . $this->link->real_escape_string($str) . '\'';
-    }
-
-    /**
-     * Will fullquote all values in the one-dimensional array so they are ready to "implode" for an sql query.
-     *
-     * @param array $arr Array with values (either associative or non-associative array)
-     * @param string $table Table name for which to quote
-     * @param bool|array|string $noQuote List/array of keys NOT to quote (eg. SQL functions) - ONLY for associative arrays
-     * @param bool $allowNull Whether to allow NULL values
-     * @return array The input array with the values quoted
-     * @see cleanIntArray()
-     */
-    public function fullQuoteArray($arr, $table, $noQuote = false, $allowNull = false)
-    {
-        $this->logDeprecation();
-        if (is_string($noQuote)) {
-            $noQuote = explode(',', $noQuote);
-        } elseif (!is_array($noQuote)) {
-            $noQuote = (bool)$noQuote;
-        }
-        if ($noQuote === true) {
-            return $arr;
-        }
-        foreach ($arr as $k => $v) {
-            if ($noQuote === false || !in_array($k, $noQuote)) {
-                $arr[$k] = $this->fullQuoteStr($v, $table, $allowNull);
-            }
-        }
-        return $arr;
-    }
-
-    /**
-     * Substitution for PHP function "addslashes()"
-     * Use this function instead of the PHP addslashes() function when you build queries - this will prepare your code for DBAL.
-     * NOTICE: You must wrap the output of this function in SINGLE QUOTES to be DBAL compatible. Unless you have to apply the single quotes yourself you should rather use ->fullQuoteStr()!
-     *
-     * @param string $str Input string
-     * @param string $table Table name for which to quote string. Just enter the table that the field-value is selected from (and any DBAL will look up which handler to use and then how to quote the string!).
-     * @return string Output string; Quotes (" / ') and \ will be backslashed (or otherwise based on DBAL handler)
-     * @see quoteStr()
-     */
-    public function quoteStr($str, $table)
-    {
-        $this->logDeprecation();
-        if (!$this->isConnected) {
-            $this->connectDB();
-        }
-        return $this->link->real_escape_string($str);
-    }
-
-    /**
-     * Escaping values for SQL LIKE statements.
-     *
-     * @param string $str Input string
-     * @param string $table Table name for which to escape string. Just enter the table that the field-value is selected from (and any DBAL will look up which handler to use and then how to quote the string!).
-     * @return string Output string; % and _ will be escaped with \ (or otherwise based on DBAL handler)
-     * @see quoteStr()
-     */
-    public function escapeStrForLike($str, $table)
-    {
-        $this->logDeprecation();
-        return addcslashes($str, '_%');
-    }
-
-    /**
-     * Will convert all values in the one-dimensional array to integers.
-     * Useful when you want to make sure an array contains only integers before imploding them in a select-list.
-     *
-     * @param array $arr Array with values
-     * @return array The input array with all values cast to (int)
-     * @see cleanIntList()
-     */
-    public function cleanIntArray($arr)
-    {
-        $this->logDeprecation();
-        return array_map('intval', $arr);
-    }
-
-    /**
-     * Will force all entries in the input comma list to integers
-     * Useful when you want to make sure a commalist of supposed integers really contain only integers; You want to know that when you don't trust content that could go into an SQL statement.
-     *
-     * @param string $list List of comma-separated values which should be integers
-     * @return string The input list but with every value cast to (int)
-     * @see cleanIntArray()
-     */
-    public function cleanIntList($list)
-    {
-        $this->logDeprecation();
-        return implode(',', GeneralUtility::intExplode(',', $list));
-    }
-
-    /**
-     * Removes the prefix "ORDER BY" from the input string.
-     * This function is used when you call the exec_SELECTquery() function and want to pass the ORDER BY parameter by can't guarantee that "ORDER BY" is not prefixed.
-     * Generally; This function provides a work-around to the situation where you cannot pass only the fields by which to order the result.
-     *
-     * @param string $str eg. "ORDER BY title, uid
-     * @return string eg. "title, uid
-     * @see exec_SELECTquery(), stripGroupBy()
-     */
-    public function stripOrderBy($str)
-    {
-        $this->logDeprecation();
-        return preg_replace('/^(?:ORDER[[:space:]]*BY[[:space:]]*)+/i', '', trim($str));
-    }
-
-    /**
-     * Removes the prefix "GROUP BY" from the input string.
-     * This function is used when you call the SELECTquery() function and want to pass the GROUP BY parameter by can't guarantee that "GROUP BY" is not prefixed.
-     * Generally; This function provides a work-around to the situation where you cannot pass only the fields by which to order the result.
-     *
-     * @param string $str eg. "GROUP BY title, uid
-     * @return string eg. "title, uid
-     * @see exec_SELECTquery(), stripOrderBy()
-     */
-    public function stripGroupBy($str)
-    {
-        $this->logDeprecation();
-        return preg_replace('/^(?:GROUP[[:space:]]*BY[[:space:]]*)+/i', '', trim($str));
-    }
-
-    /**
-     * Returns the date and time formats compatible with the given database table.
-     *
-     * @param string $table Table name for which to return an empty date. Just enter the table that the field-value is selected from (and any DBAL will look up which handler to use and then how date and time should be formatted).
-     * @return array
-     */
-    public function getDateTimeFormats($table)
-    {
-        $this->logDeprecation();
-        return QueryHelper::getDateTimeFormats();
-    }
-
-    /**
-     * Creates SELECT query components for selecting fields ($select) from two/three tables joined
-     * Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
-     * The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local  / [$mm_table].uid_foreign <--> [$foreign_table].uid
-     * The function is very useful for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $GLOBALS['TCA'] in Inside TYPO3 for more details.
-     *
-     * @param string $select See exec_SELECT_mm_query()
-     * @param string $local_table See exec_SELECT_mm_query()
-     * @param string $mm_table See exec_SELECT_mm_query()
-     * @param string $foreign_table See exec_SELECT_mm_query()
-     * @param string $whereClause See exec_SELECT_mm_query()
-     * @param string $groupBy See exec_SELECT_mm_query()
-     * @param string $orderBy See exec_SELECT_mm_query()
-     * @param string $limit See exec_SELECT_mm_query()
-     * @return array SQL query components
-     */
-    protected function getSelectMmQueryParts($select, $local_table, $mm_table, $foreign_table, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '')
-    {
-        $foreign_table_as = $foreign_table == $local_table ? $foreign_table . StringUtility::getUniqueId('_join') : '';
-        $mmWhere = $local_table ? $local_table . '.uid=' . $mm_table . '.uid_local' : '';
-        $mmWhere .= ($local_table and $foreign_table) ? ' AND ' : '';
-        $tables = ($local_table ? $local_table . ',' : '') . $mm_table;
-        if ($foreign_table) {
-            $mmWhere .= ($foreign_table_as ?: $foreign_table) . '.uid=' . $mm_table . '.uid_foreign';
-            $tables .= ',' . $foreign_table . ($foreign_table_as ? ' AS ' . $foreign_table_as : '');
-        }
-        return [
-            'SELECT' => $select,
-            'FROM' => $tables,
-            'WHERE' => $mmWhere . ' ' . $whereClause,
-            'GROUPBY' => $groupBy,
-            'ORDERBY' => $orderBy,
-            'LIMIT' => $limit
-        ];
-    }
-
-    /**************************************
-     *
-     * MySQL(i) wrapper functions
-     * (For use in your applications)
-     *
-     **************************************/
-    /**
-     * Executes query
-     * MySQLi query() wrapper function
-     * Beware: Use of this method should be avoided as it is experimentally supported by DBAL. You should consider
-     * using exec_SELECTquery() and similar methods instead.
-     *
-     * @param string $query Query to execute
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function sql_query($query)
-    {
-        $this->logDeprecation();
-        $res = $this->query($query);
-        if ($this->debugOutput) {
-            $this->debug('sql_query', $query);
-        }
-        return $res;
-    }
-
-    /**
-     * Returns the error status on the last query() execution
-     *
-     * @return string MySQLi error string.
-     */
-    public function sql_error()
-    {
-        $this->logDeprecation();
-        return $this->link->error;
-    }
-
-    /**
-     * Returns the error number on the last query() execution
-     *
-     * @return int MySQLi error number
-     */
-    public function sql_errno()
-    {
-        $this->logDeprecation();
-        return $this->link->errno;
-    }
-
-    /**
-     * Returns the number of selected rows.
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @return int Number of resulting rows
-     */
-    public function sql_num_rows($res)
-    {
-        $this->logDeprecation();
-        if ($this->debug_check_recordset($res)) {
-            return $res->num_rows;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Returns an associative array that corresponds to the fetched row, or FALSE if there are no more rows.
-     * MySQLi fetch_assoc() wrapper function
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @return array|bool Associative array of result row.
-     */
-    public function sql_fetch_assoc($res)
-    {
-        $this->logDeprecation();
-        if ($this->debug_check_recordset($res)) {
-            $result = $res->fetch_assoc();
-            if ($result === null) {
-                // Needed for compatibility
-                $result = false;
-            }
-            return $result;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Returns an array that corresponds to the fetched row, or FALSE if there are no more rows.
-     * The array contains the values in numerical indices.
-     * MySQLi fetch_row() wrapper function
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @return array|bool Array with result rows.
-     */
-    public function sql_fetch_row($res)
-    {
-        $this->logDeprecation();
-        if ($this->debug_check_recordset($res)) {
-            $result = $res->fetch_row();
-            if ($result === null) {
-                // Needed for compatibility
-                $result = false;
-            }
-            return $result;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Free result memory
-     * free_result() wrapper function
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @return bool Returns TRUE on success or FALSE on failure.
-     */
-    public function sql_free_result($res)
-    {
-        $this->logDeprecation();
-        if ($this->debug_check_recordset($res) && is_object($res)) {
-            $res->free();
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Get the ID generated from the previous INSERT operation
-     *
-     * @return int The uid of the last inserted record.
-     */
-    public function sql_insert_id()
-    {
-        $this->logDeprecation();
-        return $this->link->insert_id;
-    }
-
-    /**
-     * Returns the number of rows affected by the last INSERT, UPDATE or DELETE query
-     *
-     * @return int Number of rows affected by last query
-     */
-    public function sql_affected_rows()
-    {
-        return $this->link->affected_rows;
-    }
-
-    /**
-     * Move internal result pointer
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @param int $seek Seek result number.
-     * @return bool Returns TRUE on success or FALSE on failure.
-     */
-    public function sql_data_seek($res, $seek)
-    {
-        $this->logDeprecation();
-        if ($this->debug_check_recordset($res)) {
-            return $res->data_seek($seek);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Get the type of the specified field in a result
-     * mysql_field_type() wrapper function
-     *
-     * @param bool|\mysqli_result|object $res MySQLi result object / DBAL object
-     * @param int $pointer Field index.
-     * @return string Returns the name of the specified field index, or FALSE on error
-     */
-    public function sql_field_type($res, $pointer)
-    {
-        // mysql_field_type compatibility map
-        // taken from: http://www.php.net/manual/en/mysqli-result.fetch-field-direct.php#89117
-        // Constant numbers see http://php.net/manual/en/mysqli.constants.php
-        $mysql_data_type_hash = [
-            1=>'tinyint',
-            2=>'smallint',
-            3=>'int',
-            4=>'float',
-            5=>'double',
-            7=>'timestamp',
-            8=>'bigint',
-            9=>'mediumint',
-            10=>'date',
-            11=>'time',
-            12=>'datetime',
-            13=>'year',
-            16=>'bit',
-            //252 is currently mapped to all text and blob types (MySQL 5.0.51a)
-            253=>'varchar',
-            254=>'char',
-            246=>'decimal'
-        ];
-        if ($this->debug_check_recordset($res)) {
-            $metaInfo = $res->fetch_field_direct($pointer);
-            if ($metaInfo === false) {
-                return false;
-            }
-            return $mysql_data_type_hash[$metaInfo->type];
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Open a (persistent) connection to a MySQL server
-     *
-     * @return bool|void
-     * @throws \RuntimeException
-     */
-    public function sql_pconnect()
-    {
-        if ($this->isConnected) {
-            return $this->link;
-        }
-
-        if (!extension_loaded('mysqli')) {
-            throw new \RuntimeException(
-                'Database Error: PHP mysqli extension not loaded. This is a must have for TYPO3 CMS!',
-                1271492607
-            );
-        }
-
-        $host = $this->persistentDatabaseConnection
-            ? 'p:' . $this->databaseHost
-            : $this->databaseHost;
-
-        // We are not using the TYPO3 CMS shim here as the database parameters in this class
-        // are settable externally. This requires building the connection parameter array
-        // just in time when establishing the connection.
-        $connection = \Doctrine\DBAL\DriverManager::getConnection([
-            'driver' => 'mysqli',
-            'wrapperClass' => Connection::class,
-            'host' => $host,
-            'port' => (int)$this->databasePort,
-            'unix_socket' => $this->databaseSocket,
-            'user' => $this->databaseUsername,
-            'password' => $this->databaseUserPassword,
-            'charset' => $this->connectionCharset,
-        ]);
-
-        // Mimic the previous behavior of returning false on connection errors
-        try {
-            /** @var \Doctrine\DBAL\Driver\Mysqli\MysqliConnection $mysqliConnection */
-            $mysqliConnection = $connection->getWrappedConnection();
-            $this->link = $mysqliConnection->getWrappedResourceHandle();
-        } catch (\Doctrine\DBAL\Exception\ConnectionException $exception) {
-            return false;
-        }
-
-        if ($connection->isConnected()) {
-            $this->isConnected = true;
-
-            foreach ($this->initializeCommandsAfterConnect as $command) {
-                if ($this->query($command) === false) {
-                    GeneralUtility::sysLog(
-                        'Could not initialize DB connection with query "' . $command . '": ' . $this->sql_error(),
-                        'core',
-                        GeneralUtility::SYSLOG_SEVERITY_ERROR
-                    );
-                }
-            }
-            $this->checkConnectionCharset();
-        } else {
-            // @todo This should raise an exception. Would be useful especially to work during installation.
-            $error_msg = $this->link->connect_error;
-            $this->link = null;
-            GeneralUtility::sysLog(
-                'Could not connect to MySQL server ' . $host . ' with user ' . $this->databaseUsername . ': '
-                . $error_msg,
-                'core',
-                GeneralUtility::SYSLOG_SEVERITY_FATAL
-            );
-        }
-
-        return $this->link;
-    }
-
-    /**
-     * Select a SQL database
-     *
-     * @return bool Returns TRUE on success or FALSE on failure.
-     */
-    public function sql_select_db()
-    {
-        if (!$this->isConnected) {
-            $this->connectDB();
-        }
-
-        $ret = $this->link->select_db($this->databaseName);
-        if (!$ret) {
-            GeneralUtility::sysLog(
-                'Could not select MySQL database ' . $this->databaseName . ': ' . $this->sql_error(),
-                'core',
-                GeneralUtility::SYSLOG_SEVERITY_FATAL
-            );
-        }
-        return $ret;
-    }
-
-    /**************************************
-     *
-     * SQL admin functions
-     * (For use in the Install Tool and Extension Manager)
-     *
-     **************************************/
-    /**
-     * Listing databases from current MySQL connection. NOTICE: It WILL try to select those databases and thus break selection of current database.
-     * This is only used as a service function in the (1-2-3 process) of the Install Tool.
-     * In any case a lookup should be done in the _DEFAULT handler DBMS then.
-     * Use in Install Tool only!
-     *
-     * @return array Each entry represents a database name
-     * @throws \RuntimeException
-     */
-    public function admin_get_dbs()
-    {
-        $this->logDeprecation();
-        $dbArr = [];
-        $db_list = $this->query('SELECT SCHEMA_NAME FROM information_schema.SCHEMATA');
-        if ($db_list === false) {
-            throw new \RuntimeException(
-                'MySQL Error: Cannot get tablenames: "' . $this->sql_error() . '"!',
-                1378457171
-            );
-        } else {
-            while ($row = $db_list->fetch_object()) {
-                try {
-                    $this->setDatabaseName($row->SCHEMA_NAME);
-                    if ($this->sql_select_db()) {
-                        $dbArr[] = $row->SCHEMA_NAME;
-                    }
-                } catch (\RuntimeException $exception) {
-                    // The exception happens if we cannot connect to the database
-                    // (usually due to missing permissions). This is ok here.
-                    // We catch the exception, skip the database and continue.
-                }
-            }
-        }
-        return $dbArr;
-    }
-
-    /**
-     * Returns the list of tables from the default database, TYPO3_db (quering the DBMS)
-     * In a DBAL this method should 1) look up all tables from the DBMS  of
-     * the _DEFAULT handler and then 2) add all tables *configured* to be managed by other handlers
-     *
-     * @return array Array with tablenames as key and arrays with status information as value
-     */
-    public function admin_get_tables()
-    {
-        $this->logDeprecation();
-        $whichTables = [];
-        $tables_result = $this->query('SHOW TABLE STATUS FROM `' . $this->databaseName . '`');
-        if ($tables_result !== false) {
-            while ($theTable = $tables_result->fetch_assoc()) {
-                $whichTables[$theTable['Name']] = $theTable;
-            }
-            $tables_result->free();
-        }
-        return $whichTables;
-    }
-
-    /**
-     * Returns information about each field in the $table (quering the DBMS)
-     * In a DBAL this should look up the right handler for the table and return compatible information
-     * This function is important not only for the Install Tool but probably for
-     * DBALs as well since they might need to look up table specific information
-     * in order to construct correct queries. In such cases this information should
-     * probably be cached for quick delivery.
-     *
-     * @param string $tableName Table name
-     * @return array Field information in an associative array with fieldname => field row
-     */
-    public function admin_get_fields($tableName)
-    {
-        $this->logDeprecation();
-        $output = [];
-        $columns_res = $this->query('SHOW FULL COLUMNS FROM `' . $tableName . '`');
-        if ($columns_res !== false) {
-            while ($fieldRow = $columns_res->fetch_assoc()) {
-                $output[$fieldRow['Field']] = $fieldRow;
-            }
-            $columns_res->free();
-        }
-        return $output;
-    }
-
-    /**
-     * Returns information about each index key in the $table (quering the DBMS)
-     * In a DBAL this should look up the right handler for the table and return compatible information
-     *
-     * @param string $tableName Table name
-     * @return array Key information in a numeric array
-     */
-    public function admin_get_keys($tableName)
-    {
-        $this->logDeprecation();
-        $output = [];
-        $keyRes = $this->query('SHOW KEYS FROM `' . $tableName . '`');
-        if ($keyRes !== false) {
-            while ($keyRow = $keyRes->fetch_assoc()) {
-                $output[] = $keyRow;
-            }
-            $keyRes->free();
-        }
-        return $output;
-    }
-
-    /**
-     * Returns information about the character sets supported by the current DBM
-     * This function is important not only for the Install Tool but probably for
-     * DBALs as well since they might need to look up table specific information
-     * in order to construct correct queries. In such cases this information should
-     * probably be cached for quick delivery.
-     *
-     * This is used by the Install Tool to convert tables with non-UTF8 charsets
-     * Use in Install Tool only!
-     *
-     * @return array Array with Charset as key and an array of "Charset", "Description", "Default collation", "Maxlen" as values
-     */
-    public function admin_get_charsets()
-    {
-        $this->logDeprecation();
-        $output = [];
-        $columns_res = $this->query('SHOW CHARACTER SET');
-        if ($columns_res !== false) {
-            while ($row = $columns_res->fetch_assoc()) {
-                $output[$row['Charset']] = $row;
-            }
-            $columns_res->free();
-        }
-        return $output;
-    }
-
-    /**
-     * mysqli() wrapper function, used by the Install Tool and EM for all queries regarding management of the database!
-     *
-     * @param string $query Query to execute
-     * @return bool|\mysqli_result|object MySQLi result object / DBAL object
-     */
-    public function admin_query($query)
-    {
-        $this->logDeprecation();
-        $res = $this->query($query);
-        if ($this->debugOutput) {
-            $this->debug('admin_query', $query);
-        }
-        return $res;
-    }
-
-    /******************************
-     *
-     * Connect handling
-     *
-     ******************************/
-
-    /**
-     * Set database host
-     *
-     * @param string $host
-     */
-    public function setDatabaseHost($host = 'localhost')
-    {
-        $this->disconnectIfConnected();
-        $this->databaseHost = $host;
-    }
-
-    /**
-     * Set database port
-     *
-     * @param int $port
-     */
-    public function setDatabasePort($port = 3306)
-    {
-        $this->disconnectIfConnected();
-        $this->databasePort = (int)$port;
-    }
-
-    /**
-     * Set database socket
-     *
-     * @param string|NULL $socket
-     */
-    public function setDatabaseSocket($socket = null)
-    {
-        $this->disconnectIfConnected();
-        $this->databaseSocket = $socket;
-    }
-
-    /**
-     * Set database name
-     *
-     * @param string $name
-     */
-    public function setDatabaseName($name)
-    {
-        $this->disconnectIfConnected();
-        $this->databaseName = $name;
-    }
-
-    /**
-     * Set database username
-     *
-     * @param string $username
-     */
-    public function setDatabaseUsername($username)
-    {
-        $this->disconnectIfConnected();
-        $this->databaseUsername = $username;
-    }
-
-    /**
-     * Set database password
-     *
-     * @param string $password
-     */
-    public function setDatabasePassword($password)
-    {
-        $this->disconnectIfConnected();
-        $this->databaseUserPassword = $password;
-    }
-
-    /**
-     * Set persistent database connection
-     *
-     * @param bool $persistentDatabaseConnection
-     * @see http://php.net/manual/de/mysqli.persistconns.php
-     */
-    public function setPersistentDatabaseConnection($persistentDatabaseConnection)
-    {
-        $this->disconnectIfConnected();
-        $this->persistentDatabaseConnection = (bool)$persistentDatabaseConnection;
-    }
-
-    /**
-     * Set connection compression. Might be an advantage, if SQL server is not on localhost
-     *
-     * @param bool $connectionCompression TRUE if connection should be compressed
-     */
-    public function setConnectionCompression($connectionCompression)
-    {
-        $this->disconnectIfConnected();
-        $this->connectionCompression = (bool)$connectionCompression;
-    }
-
-    /**
-     * Set commands to be fired after connection was established
-     *
-     * @param array $commands List of SQL commands to be executed after connect
-     */
-    public function setInitializeCommandsAfterConnect(array $commands)
-    {
-        $this->disconnectIfConnected();
-        $this->initializeCommandsAfterConnect = $commands;
-    }
-
-    /**
-     * Set the charset that should be used for the MySQL connection.
-     * The given value will be passed on to mysqli_set_charset().
-     *
-     * The default value of this setting is utf8.
-     *
-     * @param string $connectionCharset The connection charset that will be passed on to mysqli_set_charset() when connecting the database. Default is utf8.
-     */
-    public function setConnectionCharset($connectionCharset = 'utf8')
-    {
-        $this->disconnectIfConnected();
-        $this->connectionCharset = $connectionCharset;
-    }
-
-    /**
-     * Connects to database for TYPO3 sites:
-     *
-     * @throws \RuntimeException
-     * @throws \UnexpectedValueException
-     */
-    public function connectDB()
-    {
-        $this->logDeprecation();
-        // Early return if connected already
-        if ($this->isConnected) {
-            return;
-        }
-
-        if (!$this->databaseName) {
-            throw new \RuntimeException(
-                'TYPO3 Fatal Error: No database selected!',
-                1270853882
-            );
-        }
-
-        if ($this->sql_pconnect()) {
-            if (!$this->sql_select_db()) {
-                throw new \RuntimeException(
-                    'TYPO3 Fatal Error: Cannot connect to the current database, "' . $this->databaseName . '"!',
-                    1270853883
-                );
-            }
-        } else {
-            throw new \RuntimeException(
-                'TYPO3 Fatal Error: The current username, password or host was not accepted when the connection to the database was attempted to be established!',
-                1270853884
-            );
-        }
-
-        // Prepare user defined objects (if any) for hooks which extend query methods
-        $this->preProcessHookObjects = [];
-        $this->postProcessHookObjects = [];
-        if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_db.php']['queryProcessors'])) {
-            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_db.php']['queryProcessors'] as $className) {
-                $hookObject = GeneralUtility::makeInstance($className);
-                if (!(
-                    $hookObject instanceof PreProcessQueryHookInterface
-                    || $hookObject instanceof PostProcessQueryHookInterface
-                )) {
-                    throw new \UnexpectedValueException(
-                        '$hookObject must either implement interface TYPO3\\CMS\\Typo3DbLegacy\\Database\\PreProcessQueryHookInterface or interface TYPO3\\CMS\\Typo3DbLegacy\\Database\\PostProcessQueryHookInterface',
-                        1299158548
-                    );
-                }
-                if ($hookObject instanceof PreProcessQueryHookInterface) {
-                    $this->preProcessHookObjects[] = $hookObject;
-                }
-                if ($hookObject instanceof PostProcessQueryHookInterface) {
-                    $this->postProcessHookObjects[] = $hookObject;
-                }
-            }
-        }
-    }
-
-    /**
-     * Checks if database is connected
-     *
-     * @return bool
-     */
-    public function isConnected()
-    {
-        // We think we're still connected
-        if ($this->isConnected) {
-            // Check if this is really the case or if the database server has gone away for some reason
-            // Using mysqlnd ping() does not reconnect (which we would not want anyway since charset etc would not be reinitialized that way)
-            $this->isConnected = $this->link->ping();
-        }
-        return $this->isConnected;
-    }
-
-    /**
-     * Checks if the current connection character set has the same value
-     * as the connectionCharset variable.
-     *
-     * To determine the character set these MySQL session variables are
-     * checked: character_set_client, character_set_results and
-     * character_set_connection.
-     *
-     * If the character set does not match or if the session variables
-     * can not be read a RuntimeException is thrown.
-     *
-     * @throws \RuntimeException
-     */
-    protected function checkConnectionCharset()
-    {
-        $sessionResult = $this->sql_query('SHOW SESSION VARIABLES LIKE \'character_set%\'');
-
-        if ($sessionResult === false) {
-            GeneralUtility::sysLog(
-                'Error while retrieving the current charset session variables from the database: ' . $this->sql_error(),
-                'core',
-                GeneralUtility::SYSLOG_SEVERITY_ERROR
-            );
-            throw new \RuntimeException(
-                'TYPO3 Fatal Error: Could not determine the current charset of the database.',
-                1381847136
-            );
-        }
-
-        $charsetVariables = [];
-        while (($row = $this->sql_fetch_row($sessionResult)) !== false) {
-            $variableName = $row[0];
-            $variableValue = $row[1];
-            $charsetVariables[$variableName] = $variableValue;
-        }
-        $this->sql_free_result($sessionResult);
-
-        // These variables are set with the "Set names" command which was
-        // used in the past. This is why we check them.
-        $charsetRequiredVariables = [
-            'character_set_client',
-            'character_set_results',
-            'character_set_connection',
-        ];
-
-        $hasValidCharset = true;
-        foreach ($charsetRequiredVariables as $variableName) {
-            if (empty($charsetVariables[$variableName])) {
-                GeneralUtility::sysLog(
-                    'A required session variable is missing in the current MySQL connection: ' . $variableName,
-                    'core',
-                    GeneralUtility::SYSLOG_SEVERITY_ERROR
-                );
-                throw new \RuntimeException(
-                    'TYPO3 Fatal Error: Could not determine the value of the database session variable: ' . $variableName,
-                    1381847779
-                );
-            }
-
-            if ($charsetVariables[$variableName] !== $this->connectionCharset) {
-                $hasValidCharset = false;
-                break;
-            }
-        }
-
-        if (!$hasValidCharset) {
-            throw new \RuntimeException(
-                'It looks like the character set ' . $this->connectionCharset . ' is not used for this connection even though it is configured as connection charset. ' .
-                'This TYPO3 installation is using the $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'setDBinit\'] property with the following value: "' .
-                $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'] . '". Please make sure that this command does not overwrite the configured charset. ' .
-                'Please note that for the TYPO3 database everything other than utf8 is unsupported since version 4.7.',
-                1389697515
-            );
-        }
-    }
-
-    /**
-     * Disconnect from database if connected
-     */
-    protected function disconnectIfConnected()
-    {
-        if ($this->isConnected) {
-            $this->link->close();
-            $this->isConnected = false;
-        }
-    }
-
-    /**
-     * Returns current database handle
-     *
-     * @return \mysqli|NULL
-     */
-    public function getDatabaseHandle()
-    {
-        $this->logDeprecation();
-        return $this->link;
-    }
-
-    /**
-     * Set current database handle, usually \mysqli
-     *
-     * @param \mysqli $handle
-     */
-    public function setDatabaseHandle($handle)
-    {
-        $this->link = $handle;
-    }
-
-    /**
-     * Get the MySQL server version
-     *
-     * @return string
-     */
-    public function getServerVersion()
-    {
-        $this->logDeprecation();
-        return $this->link->server_info;
-    }
-
-    /******************************
-     *
-     * Debugging
-     *
-     ******************************/
-    /**
-     * Debug function: Outputs error if any
-     *
-     * @param string $func Function calling debug()
-     * @param string $query Last query if not last built query
-     */
-    public function debug($func, $query = '')
-    {
-        $this->logDeprecation();
-        $error = $this->sql_error();
-        if ($error || (int)$this->debugOutput === 2) {
-            \TYPO3\CMS\Core\Utility\DebugUtility::debug(
-                [
-                    'caller' => \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection::class . '::' . $func,
-                    'ERROR' => $error,
-                    'lastBuiltQuery' => $query ? $query : $this->debug_lastBuiltQuery,
-                    'debug_backtrace' => \TYPO3\CMS\Core\Utility\DebugUtility::debugTrail()
-                ],
-                $func,
-                is_object($GLOBALS['error']) && @is_callable([$GLOBALS['error'], 'debug'])
-                    ? ''
-                    : 'DB Error'
-            );
-        }
-    }
-
-    /**
-     * Checks if record set is valid and writes debugging information into devLog if not.
-     *
-     * @param bool|\mysqli_result|object MySQLi result object / DBAL object
-     * @return bool TRUE if the  record set is valid, FALSE otherwise
-     */
-    public function debug_check_recordset($res)
-    {
-        $this->logDeprecation();
-        if ($res !== false && $res !== null) {
-            return true;
-        }
-        $trace = debug_backtrace(0);
-        array_shift($trace);
-        $msg = 'Invalid database result detected: function TYPO3\\CMS\\Typo3DbLegacy\\Database\\DatabaseConnection->'
-            . $trace[0]['function'] . ' called from file ' . substr($trace[0]['file'], (strlen(PATH_site) + 2))
-            . ' in line ' . $trace[0]['line'] . '.';
-        GeneralUtility::sysLog(
-            $msg . ' Use a devLog extension to get more details.',
-            'core',
-            GeneralUtility::SYSLOG_SEVERITY_ERROR
-        );
-        // Send to devLog if enabled
-        if (TYPO3_DLOG) {
-            $debugLogData = [
-                'SQL Error' => $this->sql_error(),
-                'Backtrace' => $trace
-            ];
-            if ($this->debug_lastBuiltQuery) {
-                $debugLogData = ['SQL Query' => $this->debug_lastBuiltQuery] + $debugLogData;
-            }
-            GeneralUtility::devLog($msg, 'Core/t3lib_db', 3, $debugLogData);
-        }
-        return false;
-    }
-
-    /**
-     * Explain select queries
-     * If $this->explainOutput is set, SELECT queries will be explained here. Only queries with more than one possible result row will be displayed.
-     * The output is either printed as raw HTML output or embedded into the TS admin panel (checkbox must be enabled!)
-     *
-     * @todo Feature is not DBAL-compliant
-     *
-     * @param string $query SQL query
-     * @param string $from_table Table(s) from which to select. This is what comes right after "FROM ...". Required value.
-     * @param int $row_count Number of resulting rows
-     * @return bool TRUE if explain was run, FALSE otherwise
-     */
-    protected function explain($query, $from_table, $row_count)
-    {
-        $debugAllowedForIp = GeneralUtility::cmpIP(
-            GeneralUtility::getIndpEnv('REMOTE_ADDR'),
-            $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']
-        );
-        if (
-            (int)$this->explainOutput == 1
-            || ((int)$this->explainOutput == 2 && $debugAllowedForIp)
-        ) {
-            // Raw HTML output
-            $explainMode = 1;
-        } elseif ((int)$this->explainOutput == 3) {
-            // Embed the output into the TS admin panel
-            $explainMode = 2;
-        } else {
-            return false;
-        }
-        $error = $this->sql_error();
-        $trail = \TYPO3\CMS\Core\Utility\DebugUtility::debugTrail();
-        $explain_tables = [];
-        $explain_output = [];
-        $res = $this->sql_query('EXPLAIN ' . $query, $this->link);
-        if (is_a($res, '\\mysqli_result')) {
-            while ($tempRow = $this->sql_fetch_assoc($res)) {
-                $explain_output[] = $tempRow;
-                $explain_tables[] = $tempRow['table'];
-            }
-            $this->sql_free_result($res);
-        }
-        $indices_output = [];
-        // Notice: Rows are skipped if there is only one result, or if no conditions are set
-        if ($explain_output[0]['rows'] > 1 || $explain_output[0]['type'] === 'ALL') {
-            // Only enable output if it's really useful
-            $debug = true;
-            foreach ($explain_tables as $table) {
-                $tableRes = $this->sql_query('SHOW TABLE STATUS LIKE \'' . $table . '\'');
-                $isTable = $this->sql_num_rows($tableRes);
-                if ($isTable) {
-                    $res = $this->sql_query('SHOW INDEX FROM ' . $table, $this->link);
-                    if (is_a($res, '\\mysqli_result')) {
-                        while ($tempRow = $this->sql_fetch_assoc($res)) {
-                            $indices_output[] = $tempRow;
-                        }
-                        $this->sql_free_result($res);
-                    }
-                }
-                $this->sql_free_result($tableRes);
-            }
-        } else {
-            $debug = false;
-        }
-        if ($debug) {
-            if ($explainMode) {
-                $data = [];
-                $data['query'] = $query;
-                $data['trail'] = $trail;
-                $data['row_count'] = $row_count;
-                if ($error) {
-                    $data['error'] = $error;
-                }
-                if (!empty($explain_output)) {
-                    $data['explain'] = $explain_output;
-                }
-                if (!empty($indices_output)) {
-                    $data['indices'] = $indices_output;
-                }
-                if ($explainMode == 1) {
-                    \TYPO3\CMS\Core\Utility\DebugUtility::debug($data, 'Tables: ' . $from_table, 'DB SQL EXPLAIN');
-                } elseif ($explainMode == 2) {
-                    /** @var TimeTracker $timeTracker */
-                    $timeTracker = GeneralUtility::makeInstance(TimeTracker::class);
-                    $timeTracker->setTSselectQuery($data);
-                }
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Serialize destructs current connection
-     *
-     * @return array All protected properties that should be saved
-     */
-    public function __sleep()
-    {
-        $this->disconnectIfConnected();
-        return [
-            'debugOutput',
-            'explainOutput',
-            'databaseHost',
-            'databasePort',
-            'databaseSocket',
-            'databaseName',
-            'databaseUsername',
-            'databaseUserPassword',
-            'persistentDatabaseConnection',
-            'connectionCompression',
-            'initializeCommandsAfterConnect',
-            'default_charset',
-        ];
-    }
-
-    /**
-     * function to call a deprecation log entry (but only once per request / class)
-     */
-    protected function logDeprecation()
-    {
-        if (!$this->deprecationWarningThrown) {
-            $this->deprecationWarningThrown = true;
-            GeneralUtility::deprecationLog('DatabaseConnection a.k.a. $["TYPO3_DB"] has been marked as deprecated in'
-            . ' TYPO3 v8 and will be removed in TYPO3 v9. Please use the newly available ConnectionPool and QueryBuilder'
-            . ' classes.');
-        }
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Classes/Database/PostProcessQueryHookInterface.php b/typo3/sysext/typo3db_legacy/Classes/Database/PostProcessQueryHookInterface.php
deleted file mode 100644 (file)
index f6e7a1f..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Interface for classes which hook into \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection
- * and do additional processing after a query has been executed.
- */
-interface PostProcessQueryHookInterface
-{
-    /**
-     * Post-processor for the SELECTquery method.
-     *
-     * @param string $select_fields Fields to be selected
-     * @param string $from_table Table to select data from
-     * @param string $where_clause Where clause
-     * @param string $groupBy Group by statement
-     * @param string $orderBy Order by statement
-     * @param int $limit Database return limit
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_SELECTquery_postProcessAction(&$select_fields, &$from_table, &$where_clause, &$groupBy, &$orderBy, &$limit, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Post-processor for the exec_INSERTquery method.
-     *
-     * @param string $table Database table name
-     * @param array $fieldsValues Field values as key => value pairs
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_INSERTquery_postProcessAction(&$table, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Post-processor for the exec_INSERTmultipleRows method.
-     *
-     * @param string $table Database table name
-     * @param array $fields Field names
-     * @param array $rows Table rows
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_INSERTmultipleRows_postProcessAction(&$table, array &$fields, array &$rows, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Post-processor for the exec_UPDATEquery method.
-     *
-     * @param string $table Database table name
-     * @param string $where WHERE clause
-     * @param array $fieldsValues Field values as key => value pairs
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_UPDATEquery_postProcessAction(&$table, &$where, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Post-processor for the exec_DELETEquery method.
-     *
-     * @param string $table Database table name
-     * @param string $where WHERE clause
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_DELETEquery_postProcessAction(&$table, &$where, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Post-processor for the exec_TRUNCATEquery method.
-     *
-     * @param string $table Database table name
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function exec_TRUNCATEquery_postProcessAction(&$table, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-}
diff --git a/typo3/sysext/typo3db_legacy/Classes/Database/PreProcessQueryHookInterface.php b/typo3/sysext/typo3db_legacy/Classes/Database/PreProcessQueryHookInterface.php
deleted file mode 100644 (file)
index 15fc383..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Interface for classes which hook into \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection
- * and do additional processing before a query has been executed.
- */
-interface PreProcessQueryHookInterface
-{
-    /**
-     * Pre-processor for the SELECTquery method.
-     *
-     * @param string $select_fields Fields to be selected
-     * @param string $from_table Table to select data from
-     * @param string $where_clause Where clause
-     * @param string $groupBy Group by statement
-     * @param string $orderBy Order by statement
-     * @param int $limit Database return limit
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function SELECTquery_preProcessAction(&$select_fields, &$from_table, &$where_clause, &$groupBy, &$orderBy, &$limit, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Pre-processor for the INSERTquery method.
-     *
-     * @param string $table Database table name
-     * @param array $fieldsValues Field values as key => value pairs
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function INSERTquery_preProcessAction(&$table, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Pre-processor for the INSERTmultipleRows method.
-     * BEWARE: When using DBAL, this hook will not be called at all. Instead,
-     * INSERTquery_preProcessAction() will be invoked for each row.
-     *
-     * @param string $table Database table name
-     * @param array $fields Field names
-     * @param array $rows Table rows
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function INSERTmultipleRows_preProcessAction(&$table, array &$fields, array &$rows, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Pre-processor for the UPDATEquery method.
-     *
-     * @param string $table Database table name
-     * @param string $where WHERE clause
-     * @param array $fieldsValues Field values as key => value pairs
-     * @param string|array $noQuoteFields List/array of keys NOT to quote
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function UPDATEquery_preProcessAction(&$table, &$where, array &$fieldsValues, &$noQuoteFields, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Pre-processor for the DELETEquery method.
-     *
-     * @param string $table Database table name
-     * @param string $where WHERE clause
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function DELETEquery_preProcessAction(&$table, &$where, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-
-    /**
-     * Pre-processor for the TRUNCATEquery method.
-     *
-     * @param string $table Database table name
-     * @param \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject
-     */
-    public function TRUNCATEquery_preProcessAction(&$table, \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection $parentObject);
-}
diff --git a/typo3/sysext/typo3db_legacy/Classes/Database/PreparedStatement.php b/typo3/sysext/typo3db_legacy/Classes/Database/PreparedStatement.php
deleted file mode 100644 (file)
index 91bdbeb..0000000
+++ /dev/null
@@ -1,688 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Crypto\Random;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * @deprecated  ------------- THE WHOLE CLASS WILL BE REMOVED IN TYPO3 v9 ---------------------
- * This class has been superseded by Doctrine DBAL in TYPO3 v8, and will be removed in TYPO3 v9
- * --------------------------------------------------------------------------------------------
- *
- * TYPO3 prepared statement for DatabaseConnection
- *
- * USE:
- * In all TYPO3 scripts when you need to create a prepared query:
- * <code>
- * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'pages', 'uid = :uid');
- * $statement->execute(array(':uid' => 2));
- * while (($row = $statement->fetch()) !== FALSE) {
- * ...
- * }
- * $statement->free();
- * </code>
- */
-class PreparedStatement
-{
-    /**
-     * Represents the SQL NULL data type.
-     *
-     * @var int
-     */
-    const PARAM_NULL = 0;
-
-    /**
-     * Represents the SQL INTEGER data type.
-     *
-     * @var int
-     */
-    const PARAM_INT = 1;
-
-    /**
-     * Represents the SQL CHAR, VARCHAR, or other string data type.
-     *
-     * @var int
-     */
-    const PARAM_STR = 2;
-
-    /**
-     * Represents a boolean data type.
-     *
-     * @var int
-     */
-    const PARAM_BOOL = 3;
-
-    /**
-     * Automatically detects underlying type
-     *
-     * @var int
-     */
-    const PARAM_AUTOTYPE = 4;
-
-    /**
-     * Specifies that the fetch method shall return each row as an array indexed by
-     * column name as returned in the corresponding result set. If the result set
-     * contains multiple columns with the same name, \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::FETCH_ASSOC
-     * returns only a single value per column name.
-     *
-     * @var int
-     */
-    const FETCH_ASSOC = 2;
-
-    /**
-     * Specifies that the fetch method shall return each row as an array indexed by
-     * column number as returned in the corresponding result set, starting at column 0.
-     *
-     * @var int
-     */
-    const FETCH_NUM = 3;
-
-    /**
-     * Query to be executed.
-     *
-     * @var string
-     */
-    protected $query;
-
-    /**
-     * Components of the query to be executed.
-     *
-     * @var array
-     */
-    protected $precompiledQueryParts;
-
-    /**
-     * Table (used to call $GLOBALS['TYPO3_DB']->fullQuoteStr().
-     *
-     * @var string
-     */
-    protected $table;
-
-    /**
-     * Binding parameters.
-     *
-     * @var array
-     */
-    protected $parameters;
-
-    /**
-     * Default fetch mode.
-     *
-     * @var int
-     */
-    protected $defaultFetchMode = self::FETCH_ASSOC;
-
-    /**
-     * MySQLi statement object / DBAL object
-     *
-     * @var \mysqli_stmt|object
-     */
-    protected $statement;
-
-    /**
-     * @var array
-     */
-    protected $fields;
-
-    /**
-     * @var array
-     */
-    protected $buffer;
-
-    /**
-     * Random token which is wrapped around the markers
-     * that will be replaced by user input.
-     *
-     * @var string
-     */
-    protected $parameterWrapToken;
-
-    /**
-     * Creates a new PreparedStatement. Either $query or $queryComponents
-     * should be used. Typically $query will be used by native MySQL TYPO3_DB
-     * on a ready-to-be-executed query. On the other hand, DBAL will have
-     * parse the query and will be able to safely know where parameters are used
-     * and will use $queryComponents instead.
-     *
-     * This constructor may only be used by \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection
-     *
-     * @param string $query SQL query to be executed
-     * @param string $table FROM table, used to call $GLOBALS['TYPO3_DB']->fullQuoteStr().
-     * @param array $precompiledQueryParts Components of the query to be executed
-     * @access private
-     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use Doctrine DBAL as it does PreparedStatements built-in
-     */
-    public function __construct($query, $table, array $precompiledQueryParts = [])
-    {
-        GeneralUtility::logDeprecatedFunction();
-        $this->query = $query;
-        $this->precompiledQueryParts = $precompiledQueryParts;
-        $this->table = $table;
-        $this->parameters = [];
-
-        // Test if named placeholders are used
-        if ($this->hasNamedPlaceholders($query) || !empty($precompiledQueryParts)) {
-            $this->statement = null;
-        } else {
-            // Only question mark placeholders are used
-            $this->statement = $GLOBALS['TYPO3_DB']->prepare_PREPAREDquery($this->query, $this->precompiledQueryParts);
-        }
-
-        $this->parameterWrapToken = $this->generateParameterWrapToken();
-    }
-
-    /**
-     * Binds an array of values to corresponding named or question mark placeholders in the SQL
-     * statement that was use to prepare the statement.
-     *
-     * Example 1:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = ? AND bug_status = ?');
-     * $statement->bindValues(array('goofy', 'FIXED'));
-     * </code>
-     *
-     * Example 2:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = :nickname AND bug_status = :status');
-     * $statement->bindValues(array(':nickname' => 'goofy', ':status' => 'FIXED'));
-     * </code>
-     *
-     * @param array $values The values to bind to the parameter. The PHP type of each array value will be used to decide which PARAM_* type to use (int, string, boolean, NULL), so make sure your variables are properly casted, if needed.
-     * @return \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement The current prepared statement to allow method chaining
-     * @api
-     */
-    public function bindValues(array $values)
-    {
-        foreach ($values as $parameter => $value) {
-            $key = is_int($parameter) ? $parameter + 1 : $parameter;
-            $this->bindValue($key, $value, self::PARAM_AUTOTYPE);
-        }
-        return $this;
-    }
-
-    /**
-     * Binds a value to a corresponding named or question mark placeholder in the SQL
-     * statement that was use to prepare the statement.
-     *
-     * Example 1:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = ? AND bug_status = ?');
-     * $statement->bindValue(1, 'goofy');
-     * $statement->bindValue(2, 'FIXED');
-     * </code>
-     *
-     * Example 2:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = :nickname AND bug_status = :status');
-     * $statement->bindValue(':nickname', 'goofy');
-     * $statement->bindValue(':status', 'FIXED');
-     * </code>
-     *
-     * @param mixed $parameter Parameter identifier. For a prepared statement using named placeholders, this will be a parameter name of the form :name. For a prepared statement using question mark placeholders, this will be the 1-indexed position of the parameter.
-     * @param mixed $value The value to bind to the parameter.
-     * @param int $data_type Explicit data type for the parameter using the \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::PARAM_* constants. If not given, the PHP type of the value will be used instead (int, string, boolean).
-     * @return \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement The current prepared statement to allow method chaining
-     * @api
-     */
-    public function bindValue($parameter, $value, $data_type = self::PARAM_AUTOTYPE)
-    {
-        switch ($data_type) {
-            case self::PARAM_INT:
-                if (!is_int($value)) {
-                    throw new \InvalidArgumentException('$value is not an integer as expected: ' . $value, 1281868686);
-                }
-                break;
-            case self::PARAM_BOOL:
-                if (!is_bool($value)) {
-                    throw new \InvalidArgumentException('$value is not a boolean as expected: ' . $value, 1281868687);
-                }
-                break;
-            case self::PARAM_NULL:
-                if (!is_null($value)) {
-                    throw new \InvalidArgumentException('$value is not NULL as expected: ' . $value, 1282489834);
-                }
-                break;
-        }
-        if (!is_int($parameter) && !preg_match('/^:[\\w]+$/', $parameter)) {
-            throw new \InvalidArgumentException('Parameter names must start with ":" followed by an arbitrary number of alphanumerical characters.', 1395055513);
-        }
-        $key = is_int($parameter) ? $parameter - 1 : $parameter;
-        $this->parameters[$key] = [
-            'value' => $value,
-            'type' => $data_type == self::PARAM_AUTOTYPE ? $this->guessValueType($value) : $data_type
-        ];
-        return $this;
-    }
-
-    /**
-     * Executes the prepared statement. If the prepared statement included parameter
-     * markers, you must either:
-     * <ul>
-     * <li>call {@link \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::bindParam()} to bind PHP variables
-     * to the parameter markers: bound variables pass their value as input</li>
-     * <li>or pass an array of input-only parameter values</li>
-     * </ul>
-     *
-     * $input_parameters behave as in {@link \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::bindParams()}
-     * and work for both named parameters and question mark parameters.
-     *
-     * Example 1:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = ? AND bug_status = ?');
-     * $statement->execute(array('goofy', 'FIXED'));
-     * </code>
-     *
-     * Example 2:
-     * <code>
-     * $statement = $GLOBALS['TYPO3_DB']->prepare_SELECTquery('*', 'bugs', 'reported_by = :nickname AND bug_status = :status');
-     * $statement->execute(array(':nickname' => 'goofy', ':status' => 'FIXED'));
-     * </code>
-     *
-     * @param array $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. The PHP type of each array value will be used to decide which PARAM_* type to use (int, string, boolean, NULL), so make sure your variables are properly casted, if needed.
-     * @return bool Returns TRUE on success or FALSE on failure.
-     * @throws \InvalidArgumentException
-     * @api
-     */
-    public function execute(array $input_parameters = [])
-    {
-        $parameterValues = $this->parameters;
-        if (!empty($input_parameters)) {
-            $parameterValues = [];
-            foreach ($input_parameters as $key => $value) {
-                $parameterValues[$key] = [
-                    'value' => $value,
-                    'type' => $this->guessValueType($value)
-                ];
-            }
-        }
-
-        if ($this->statement !== null) {
-            // The statement has already been executed, we try to reset it
-            // for current run but will set it to NULL if it fails for some
-            // reason, just as if it were the first run
-            if (!@$this->statement->reset()) {
-                $this->statement = null;
-            }
-        }
-        if ($this->statement === null) {
-            // The statement has never been executed so we prepare it and
-            // store it for further reuse
-            $query = $this->query;
-            $precompiledQueryParts = $this->precompiledQueryParts;
-
-            $this->convertNamedPlaceholdersToQuestionMarks($query, $parameterValues, $precompiledQueryParts);
-            if (!empty($precompiledQueryParts)) {
-                $query = implode('', $precompiledQueryParts['queryParts']);
-            }
-            $this->statement = $GLOBALS['TYPO3_DB']->prepare_PREPAREDquery($query, $precompiledQueryParts);
-            if ($this->statement === null) {
-                return false;
-            }
-        }
-
-        $combinedTypes = '';
-        $values = [];
-        foreach ($parameterValues as $parameterValue) {
-            switch ($parameterValue['type']) {
-                case self::PARAM_NULL:
-                    $type = 's';
-                    $value = null;
-                    break;
-                case self::PARAM_INT:
-                    $type = 'i';
-                    $value = (int)$parameterValue['value'];
-                    break;
-                case self::PARAM_STR:
-                    $type = 's';
-                    $value = $parameterValue['value'];
-                    break;
-                case self::PARAM_BOOL:
-                    $type = 'i';
-                    $value = $parameterValue['value'] ? 1 : 0;
-                    break;
-                default:
-                    throw new \InvalidArgumentException(sprintf('Unknown type %s used for parameter %s.', $parameterValue['type'], $key), 1281859196);
-            }
-
-            $combinedTypes .= $type;
-            $values[] = $value;
-        }
-
-        // ->bind_param requires second up to last arguments as references
-        if (!empty($combinedTypes)) {
-            $bindParamArguments = [];
-            $bindParamArguments[] = $combinedTypes;
-            $numberOfExtraParamArguments = count($values);
-            for ($i = 0; $i < $numberOfExtraParamArguments; $i++) {
-                $bindParamArguments[] = &$values[$i];
-            }
-
-            call_user_func_array([$this->statement, 'bind_param'], $bindParamArguments);
-        }
-
-        $success = $this->statement->execute();
-
-        // Store result
-        if (!$success || $this->statement->store_result() === false) {
-            return false;
-        }
-
-        if (empty($this->fields)) {
-            // Store the list of fields
-            if ($this->statement instanceof \mysqli_stmt) {
-                $result = $this->statement->result_metadata();
-                if ($result instanceof \mysqli_result) {
-                    $fields = $result->fetch_fields();
-                    $result->close();
-                }
-            } else {
-                $fields = $this->statement->fetch_fields();
-            }
-            if (is_array($fields)) {
-                foreach ($fields as $field) {
-                    $this->fields[] = $field->name;
-                }
-            }
-        }
-
-        // New result set available
-        $this->buffer = null;
-
-        // Empty binding parameters
-        $this->parameters = [];
-
-        // Return the success flag
-        return $success;
-    }
-
-    /**
-     * Fetches a row from a result set associated with a \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement object.
-     *
-     * @param int $fetch_style Controls how the next row will be returned to the caller. This value must be one of the \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::FETCH_* constants. If omitted, default fetch mode for this prepared query will be used.
-     * @return array Array of rows or FALSE if there are no more rows.
-     * @api
-     */
-    public function fetch($fetch_style = 0)
-    {
-        if ($fetch_style == 0) {
-            $fetch_style = $this->defaultFetchMode;
-        }
-
-        if ($this->statement instanceof \mysqli_stmt) {
-            if ($this->buffer === null) {
-                $variables = [];
-                $this->buffer = [];
-                foreach ($this->fields as $field) {
-                    $this->buffer[$field] = null;
-                    $variables[] = &$this->buffer[$field];
-                }
-
-                call_user_func_array([$this->statement, 'bind_result'], $variables);
-            }
-            $success = $this->statement->fetch();
-            $columns = $this->buffer;
-        } else {
-            $columns = $this->statement->fetch();
-            $success = is_array($columns);
-        }
-
-        if ($success) {
-            $row = [];
-            foreach ($columns as $key => $value) {
-                switch ($fetch_style) {
-                    case self::FETCH_ASSOC:
-                        $row[$key] = $value;
-                        break;
-                    case self::FETCH_NUM:
-                        $row[] = $value;
-                        break;
-                    default:
-                        throw new \InvalidArgumentException('$fetch_style must be either TYPO3\\CMS\\Typo3DbLegacy\\Database\\PreparedStatement::FETCH_ASSOC or TYPO3\\CMS\\Typo3DbLegacy\\Database\\PreparedStatement::FETCH_NUM', 1281646455);
-                }
-            }
-        } else {
-            $row = false;
-        }
-
-        return $row;
-    }
-
-    /**
-     * Moves internal result pointer.
-     *
-     * @param int $rowNumber Where to place the result pointer (0 = start)
-     * @return bool Returns TRUE on success or FALSE on failure.
-     * @api
-     */
-    public function seek($rowNumber)
-    {
-        $success = $this->statement->data_seek((int)$rowNumber);
-        if ($this->statement instanceof \mysqli_stmt) {
-            // data_seek() does not return anything
-            $success = true;
-        }
-        return $success;
-    }
-
-    /**
-     * Returns an array containing all of the result set rows.
-     *
-     * @param int $fetch_style Controls the contents of the returned array as documented in {@link \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::fetch()}.
-     * @return array Array of rows.
-     * @api
-     */
-    public function fetchAll($fetch_style = 0)
-    {
-        $rows = [];
-        while (($row = $this->fetch($fetch_style)) !== false) {
-            $rows[] = $row;
-        }
-        return $rows;
-    }
-
-    /**
-     * Releases the cursor. Should always be call after having fetched rows from
-     * a query execution.
-     *
-     * @api
-     */
-    public function free()
-    {
-        $this->statement->close();
-    }
-
-    /**
-     * Returns the number of rows affected by the last SQL statement.
-     *
-     * @return int The number of rows.
-     * @api
-     */
-    public function rowCount()
-    {
-        return $this->statement->num_rows;
-    }
-
-    /**
-     * Returns the error number on the last execute() call.
-     *
-     * @return int Driver specific error code.
-     * @api
-     */
-    public function errorCode()
-    {
-        return $this->statement->errno;
-    }
-
-    /**
-     * Returns an array of error information about the last operation performed by this statement handle.
-     * The array consists of the following fields:
-     * <ol start="0">
-     * <li>Driver specific error code.</li>
-     * <li>Driver specific error message</li>
-     * </ol>
-     *
-     * @return array Array of error information.
-     */
-    public function errorInfo()
-    {
-        return [
-            $this->statement->errno,
-            $this->statement->error
-        ];
-    }
-
-    /**
-     * Sets the default fetch mode for this prepared query.
-     *
-     * @param int $mode One of the \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::FETCH_* constants
-     * @api
-     */
-    public function setFetchMode($mode)
-    {
-        switch ($mode) {
-            case self::FETCH_ASSOC:
-            case self::FETCH_NUM:
-                $this->defaultFetchMode = $mode;
-                break;
-            default:
-                throw new \InvalidArgumentException('$mode must be either TYPO3\\CMS\\Typo3DbLegacy\\Database\\PreparedStatement::FETCH_ASSOC or TYPO3\\CMS\\Typo3DbLegacy\\Database\\PreparedStatement::FETCH_NUM', 1281875340);
-        }
-    }
-
-    /**
-     * Guesses the type of a given value.
-     *
-     * @param mixed $value
-     * @return int One of the \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::PARAM_* constants
-     */
-    protected function guessValueType($value)
-    {
-        if (is_bool($value)) {
-            $type = self::PARAM_BOOL;
-        } elseif (is_int($value)) {
-            $type = self::PARAM_INT;
-        } elseif (is_null($value)) {
-            $type = self::PARAM_NULL;
-        } else {
-            $type = self::PARAM_STR;
-        }
-        return $type;
-    }
-
-    /**
-     * Returns TRUE if named placeholers are used in a query.
-     *
-     * @param string $query
-     * @return bool
-     */
-    protected function hasNamedPlaceholders($query)
-    {
-        $matches = preg_match('/(?<![\\w:]):[\\w]+\\b/', $query);
-        return $matches > 0;
-    }
-
-    /**
-     * Converts named placeholders into question mark placeholders in a query.
-     *
-     * @param string $query
-     * @param array $parameterValues
-     * @param array $precompiledQueryParts
-     */
-    protected function convertNamedPlaceholdersToQuestionMarks(&$query, array &$parameterValues, array &$precompiledQueryParts)
-    {
-        $queryPartsCount = count($precompiledQueryParts['queryParts']);
-        $newParameterValues = [];
-        $hasNamedPlaceholders = false;
-
-        if ($queryPartsCount === 0) {
-            $hasNamedPlaceholders = $this->hasNamedPlaceholders($query);
-            if ($hasNamedPlaceholders) {
-                $query = $this->tokenizeQueryParameterMarkers($query, $parameterValues);
-            }
-        } elseif (!empty($parameterValues)) {
-            $hasNamedPlaceholders = !is_int(key($parameterValues));
-            if ($hasNamedPlaceholders) {
-                for ($i = 1; $i < $queryPartsCount; $i += 2) {
-                    $key = $precompiledQueryParts['queryParts'][$i];
-                    $precompiledQueryParts['queryParts'][$i] = '?';
-                    $newParameterValues[] = $parameterValues[$key];
-                }
-            }
-        }
-
-        if ($hasNamedPlaceholders) {
-            if ($queryPartsCount === 0) {
-                // Convert named placeholders to standard question mark placeholders
-                $quotedParamWrapToken = preg_quote($this->parameterWrapToken, '/');
-                while (preg_match(
-                    '/' . $quotedParamWrapToken . '(.*?)' . $quotedParamWrapToken . '/',
-                    $query,
-                    $matches
-                )) {
-                    $key = $matches[1];
-
-                    $newParameterValues[] = $parameterValues[$key];
-                    $query = preg_replace(
-                        '/' . $quotedParamWrapToken . $key . $quotedParamWrapToken . '/',
-                        '?',
-                        $query,
-                        1
-                    );
-                }
-            }
-
-            $parameterValues = $newParameterValues;
-        }
-    }
-
-    /**
-     * Replace the markers with unpredictable token markers.
-     *
-     * @param string $query
-     * @param array $parameterValues
-     * @return string
-     * @throws \InvalidArgumentException
-     */
-    protected function tokenizeQueryParameterMarkers($query, array $parameterValues)
-    {
-        $unnamedParameterCount = 0;
-        foreach ($parameterValues as $key => $typeValue) {
-            if (!is_int($key)) {
-                if (!preg_match('/^:[\\w]+$/', $key)) {
-                    throw new \InvalidArgumentException('Parameter names must start with ":" followed by an arbitrary number of alphanumerical characters.', 1282348825);
-                }
-                // Replace the marker (not preceded by a word character or a ':' but
-                // followed by a word boundary)
-                $query = preg_replace('/(?<![\\w:])' . preg_quote($key, '/') . '\\b/', $this->parameterWrapToken . $key . $this->parameterWrapToken, $query);
-            } else {
-                $unnamedParameterCount++;
-            }
-        }
-        $parts = explode('?', $query, $unnamedParameterCount + 1);
-        $query = implode($this->parameterWrapToken . '?' . $this->parameterWrapToken, $parts);
-        return $query;
-    }
-
-    /**
-     * Generate a random token that is used to wrap the query markers
-     *
-     * @return string
-     */
-    protected function generateParameterWrapToken()
-    {
-        return '__' . GeneralUtility::makeInstance(Random::class)->generateRandomHexString(16) . '__';
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Classes/Updates/DbalAndAdodbExtractionUpdate.php b/typo3/sysext/typo3db_legacy/Classes/Updates/DbalAndAdodbExtractionUpdate.php
deleted file mode 100644 (file)
index 5df6379..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Updates;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Install\Updates\AbstractDownloadExtensionUpdate;
-
-/**
- * Installs and downloads EXT:adodb and EXT:dbal
- */
-class DbalAndAdodbExtractionUpdate extends AbstractDownloadExtensionUpdate
-{
-    /**
-     * @var string
-     */
-    protected $title = '[Optional] Install extensions "dbal" and "adodb" from TER.';
-
-    /**
-     * @var array
-     */
-    protected $extensionDetails = [
-        'adodb' => [
-            'title' => 'ADOdb',
-            'description' => 'Adds ADOdb to TYPO3',
-            'versionString' => '8.4.0',
-        ],
-        'dbal' => [
-            'title' => 'dbal',
-            'description' => 'Adds old database abstraction layer to TYPO3',
-            'versionString' => '8.4.0',
-        ]
-    ];
-
-    /**
-     * Checks if an update is needed
-     *
-     * @param string $description The description for the update
-     * @return bool Whether an update is needed (true) or not (false)
-     */
-    public function checkForUpdate(&$description)
-    {
-        $description = 'The extensions "dbal" and "adodb" have been extracted to'
-            . ' the TYPO3 Extension Repository. This update downloads the TYPO3 Extension from the TER'
-            . ' if the two extensions are still needed.';
-
-        return !$this->isWizardDone();
-    }
-
-    /**
-     * Second step: Ask user to install the extensions
-     *
-     * @param string $inputPrefix input prefix, all names of form fields have to start with this. Append custom name in [ ... ]
-     * @return string HTML output
-     */
-    public function getUserInput($inputPrefix)
-    {
-        return '
-            <div class="panel panel-danger">
-                <div class="panel-heading">Are you really sure?</div>
-                <div class="panel-body">
-                    <p>You should install EXT:adodb and EXT:dbal only if you really need it.</p>
-                    <p>This update wizard cannot check if the extension was installed before the update.</p>
-                    <p>Are you really sure, you want to install these two extensions?</p>
-                    <p>They are only needed if this instance connects to a database server that is NOT MySQL
-                    and if an active extension uses extension typo3db_legacy and a table mapping for EXT:dbal
-                    is configured.</p>
-                    <p>Loading these two extensions is a rather seldom exceptions, the vast majority of
-                    instances should say "no" here.</p>
-                    <div class="btn-group clearfix" data-toggle="buttons">
-                        <label class="btn btn-default active">
-                            <input type="radio" name="' . $inputPrefix . '[install]" value="0" checked="checked" /> no, don\'t install
-                        </label>
-                        <label class="btn btn-default">
-                            <input type="radio" name="' . $inputPrefix . '[install]" value="1" /> yes, please install
-                        </label>
-                    </div>
-                </div>
-            </div>
-        ';
-    }
-
-    /**
-     * Fetch and enable ext:adodb and ext:dbal
-     *
-     * @param array $databaseQueries Queries done in this update
-     * @param string $customMessage Custom message
-     * @return bool
-     */
-    public function performUpdate(array &$databaseQueries, &$customMessage)
-    {
-        $requestParams = GeneralUtility::_GP('install');
-        if (!isset($requestParams['values']['TYPO3\CMS\Install\Updates\DbalAndAdodbExtractionUpdate']['install'])) {
-            return false;
-        }
-        $install = (int)$requestParams['values']['TYPO3\CMS\Install\Updates\DbalAndAdodbExtractionUpdate']['install'];
-
-        if ($install === 1) {
-            // user decided to install extensions, install and mark wizard as done
-            $adodbSuccessful = $this->installExtension('adodb', $customMessage);
-            $dbalSuccessful = $this->installExtension('dbal', $customMessage);
-            if ($adodbSuccessful && $dbalSuccessful) {
-                $this->markWizardAsDone();
-                return true;
-            }
-        } else {
-            // user decided to not install extension, mark wizard as done
-            $this->markWizardAsDone();
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Migrations/Code/ClassAliasMap.php b/typo3/sysext/typo3db_legacy/Migrations/Code/ClassAliasMap.php
deleted file mode 100644 (file)
index 27940a7..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-return [
-    'TYPO3\\CMS\\Core\\Database\\DatabaseConnection' => \TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection::class,
-    'TYPO3\\CMS\\Core\\Database\\PreparedStatement' => \TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement::class,
-    'TYPO3\\CMS\\Core\\Database\\PostProcessQueryHookInterface' => \TYPO3\CMS\Typo3DbLegacy\Database\PostProcessQueryHookInterface::class,
-    'TYPO3\\CMS\\Core\\Database\\PreProcessQueryHookInterface' => \TYPO3\CMS\Typo3DbLegacy\Database\PreProcessQueryHookInterface::class,
-];
diff --git a/typo3/sysext/typo3db_legacy/Resources/Public/Icons/Extension.png b/typo3/sysext/typo3db_legacy/Resources/Public/Icons/Extension.png
deleted file mode 100644 (file)
index ef81ce2..0000000
Binary files a/typo3/sysext/typo3db_legacy/Resources/Public/Icons/Extension.png and /dev/null differ
diff --git a/typo3/sysext/typo3db_legacy/Tests/Functional/Database/DatabaseConnectionTest.php b/typo3/sysext/typo3db_legacy/Tests/Functional/Database/DatabaseConnectionTest.php
deleted file mode 100644 (file)
index 1a07d0b..0000000
+++ /dev/null
@@ -1,796 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Tests\Functional\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-use TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection;
-use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
-
-/**
- * Test case for \TYPO3\CMS\Core\Database\DatabaseConnection
- */
-class DatabaseConnectionTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
-{
-    /**
-     * @var array
-     */
-    protected $coreExtensionsToLoad = ['typo3db_legacy'];
-
-    /**
-     * @var DatabaseConnection
-     */
-    protected $subject = null;
-
-    /**
-     * @var string
-     */
-    protected $testTable = 'test_database_connection';
-
-    /**
-     * @var string
-     */
-    protected $testField = 'test_field';
-
-    /**
-     * @var string
-     */
-    protected $anotherTestField = 'another_test_field';
-
-    /**
-     * Set the test up
-     */
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->subject = $GLOBALS['TYPO3_DB'];
-        $this->subject->sql_query(
-            "CREATE TABLE {$this->testTable} (" .
-            '   id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,' .
-            "   {$this->testField} MEDIUMBLOB," .
-            "   {$this->anotherTestField} MEDIUMBLOB," .
-            '   PRIMARY KEY (id)' .
-            ') ENGINE=MyISAM DEFAULT CHARSET=utf8;'
-        );
-    }
-
-    /**
-     * Tear the test down
-     */
-    protected function tearDown()
-    {
-        $this->subject->sql_query("DROP TABLE {$this->testTable};");
-        unset($this->subject);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function selectDbReturnsTrue()
-    {
-        $this->assertTrue($this->subject->sql_select_db());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function selectDbReturnsFalse()
-    {
-        $this->expectException(\RuntimeException::class);
-        $this->expectExceptionCode(1270853883);
-        $this->expectExceptionMessage('TYPO3 Fatal Error: Cannot connect to the current database, "Foo"!');
-
-        $this->subject->setDatabaseName('Foo');
-        $this->assertFalse($this->subject->sql_select_db());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlAffectedRowsReturnsCorrectAmountOfRows()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
-        $this->assertEquals(1, $this->subject->sql_affected_rows());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlInsertIdReturnsCorrectId()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
-        $this->assertEquals(1, $this->subject->sql_insert_id());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function noSqlError()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
-        $this->assertEquals('', $this->subject->sql_error());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlErrorWhenInsertIntoInexistentField()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
-        $this->assertEquals('Unknown column \'test\' in \'field list\'', $this->subject->sql_error());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function noSqlErrorCode()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, [$this->testField => 'test']);
-        $this->assertEquals(0, $this->subject->sql_errno());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlErrorNoWhenInsertIntoInexistentField()
-    {
-        $this->subject->exec_INSERTquery($this->testTable, ['test' => 'test']);
-        $this->assertEquals(1054, $this->subject->sql_errno());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlPconnectReturnsInstanceOfMySqli()
-    {
-        $this->assertInstanceOf('mysqli', $this->subject->sql_pconnect());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function connectDbThrowsExeptionsWhenNoDatabaseIsGiven()
-    {
-        $this->expectException(\RuntimeException::class);
-        $this->expectExceptionCode(1270853882);
-
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['dummy'], [], '', false);
-        $subject->connectDB();
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function connectDbConnectsToDatabaseWithoutErrors()
-    {
-        $this->subject->connectDB();
-        $this->assertTrue($this->subject->isConnected());
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function disconnectIfConnectedDisconnects()
-    {
-        $this->assertTrue($this->subject->isConnected());
-        $this->subject->setDatabaseHost('127.0.0.1');
-        $this->assertFalse($this->subject->isConnected());
-    }
-
-    /**
-     * Data Provider for fullQuoteStrReturnsQuotedString()
-     *
-     * @see fullQuoteStrReturnsQuotedString()
-     *
-     * @return array
-     */
-    public function fullQuoteStrReturnsQuotedStringDataProvider()
-    {
-        return [
-            'NULL string with ReturnNull is allowed' => [
-                [null, true],
-                'NULL',
-            ],
-            'NULL string with ReturnNull is false' => [
-                [null, false],
-                "''",
-            ],
-            'Normal string' => [
-                ['Foo', false],
-                "'Foo'",
-            ],
-            'Single quoted string' => [
-                ["'Hello'", false],
-                "'\\'Hello\\''",
-            ],
-            'Double quoted string' => [
-                ['"Hello"', false],
-                "'\\\"Hello\\\"'",
-            ],
-            'String with internal single tick' => [
-                ['It\'s me', false],
-                "'It\\'s me'",
-            ],
-            'Slashes' => [
-                ['/var/log/syslog.log', false],
-                "'/var/log/syslog.log'",
-            ],
-            'Backslashes' => [
-                ['\\var\\log\\syslog.log', false],
-                "'\\\\var\\\\log\\\\syslog.log'",
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider fullQuoteStrReturnsQuotedStringDataProvider
-     *
-     * @param string $values
-     * @param string $expectedResult
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function fullQuoteStrReturnsQuotedString($values, $expectedResult)
-    {
-        /** @var DatabaseConnection $subject */
-        $quotedStr = $this->subject->fullQuoteStr($values[0], 'tt_content', $values[1]);
-        $this->assertEquals($expectedResult, $quotedStr);
-    }
-
-    /**
-     * Data Provider for fullQuoteArrayQuotesArray()
-     *
-     * @see fullQuoteArrayQuotesArray()
-     *
-     * @return array
-     */
-    public function fullQuoteArrayQuotesArrayDataProvider()
-    {
-        return [
-            'NULL array with ReturnNull is allowed' => [
-                [
-                    [null, null],
-                    false,
-                    true,
-                ],
-                ['NULL', 'NULL'],
-            ],
-
-            'NULL array with ReturnNull is false' => [
-                [
-                    [null, null],
-                    false,
-                    false,
-                ],
-                ["''", "''"],
-            ],
-
-            'Strings in array' => [
-                [
-                    ['Foo', 'Bar'],
-                    false,
-                    false,
-                ],
-                ["'Foo'", "'Bar'"],
-            ],
-
-            'Single quotes in array' => [
-                [
-                    ["'Hello'"],
-                    false,
-                    false,
-                ],
-                ["'\\'Hello\\''"],
-            ],
-
-            'Double quotes in array' => [
-                [
-                    ['"Hello"'],
-                    false,
-                    false,
-                ],
-                ["'\\\"Hello\\\"'"],
-            ],
-
-            'Slashes in array' => [
-                [
-                    ['/var/log/syslog.log'],
-                    false,
-                    false,
-                ],
-                ["'/var/log/syslog.log'"],
-            ],
-
-            'Backslashes in array' => [
-                [
-                    ['\var\log\syslog.log'],
-                    false,
-                    false,
-                ],
-                ["'\\\\var\\\\log\\\\syslog.log'"],
-            ],
-
-            'Strings with internal single tick' => [
-                [
-                    ['Hey!', 'It\'s me'],
-                    false,
-                    false,
-                ],
-                ["'Hey!'", "'It\\'s me'"],
-            ],
-
-            'no quotes strings from array' => [
-                [
-                    [
-                        'First' => 'Hey!',
-                        'Second' => 'It\'s me',
-                        'Third' => 'O\' Reily',
-                    ],
-                    ['First', 'Third'],
-                    false,
-                ],
-                ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
-            ],
-
-            'no quotes strings from string' => [
-                [
-                    [
-                        'First' => 'Hey!',
-                        'Second' => 'It\'s me',
-                        'Third' => 'O\' Reily',
-                    ],
-                    'First,Third',
-                    false,
-                ],
-                ['First' => 'Hey!', 'Second' => "'It\\'s me'", 'Third' => "O' Reily"],
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider fullQuoteArrayQuotesArrayDataProvider
-     *
-     * @param string $values
-     * @param string $expectedResult
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function fullQuoteArrayQuotesArray($values, $expectedResult)
-    {
-        $quotedResult = $this->subject->fullQuoteArray($values[0], $this->testTable, $values[1], $values[2]);
-        $this->assertSame($expectedResult, $quotedResult);
-    }
-
-    /**
-     * Data Provider for quoteStrQuotesDoubleQuotesCorrectly()
-     *
-     * @see quoteStrQuotesDoubleQuotesCorrectly()
-     *
-     * @return array
-     */
-    public function quoteStrQuotesCorrectlyDataProvider()
-    {
-        return [
-            'Double Quotes' => [
-                '"Hello"',
-                '\\"Hello\\"'
-            ],
-            'Single Quotes' => [
-                '\'Hello\'',
-                "\\'Hello\\'"
-            ],
-            'Slashes' => [
-                '/var/log/syslog.log',
-                '/var/log/syslog.log'
-            ],
-            'Literal Backslashes' => [
-                '\\var\\log\\syslog.log',
-                '\\\\var\\\\log\\\\syslog.log'
-            ],
-            'Fallback Literal Backslashes' => [
-                '\var\log\syslog.log',
-                '\\\\var\\\\log\\\\syslog.log'
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider quoteStrQuotesCorrectlyDataProvider
-     *
-     * @param string $string String to quote
-     * @param string $expectedResult Quoted string we expect
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function quoteStrQuotesDoubleQuotesCorrectly($string, $expectedResult)
-    {
-        $quotedString = $this->subject->quoteStr($string, $this->testTable);
-        $this->assertSame($expectedResult, $quotedString);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminQueryReturnsTrueForInsertQuery()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
-        );
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminQueryReturnsTrueForUpdateQuery()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
-        );
-        $id = $this->subject->sql_insert_id();
-        $this->assertTrue(
-            $this->subject->admin_query("UPDATE {$this->testTable} SET {$this->testField}='bar' WHERE id={$id}")
-        );
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminQueryReturnsTrueForDeleteQuery()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
-        );
-        $id = $this->subject->sql_insert_id();
-        $this->assertTrue($this->subject->admin_query("DELETE FROM {$this->testTable} WHERE id={$id}"));
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminQueryReturnsResultForSelectQuery()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo')")
-        );
-        $res = $this->subject->admin_query("SELECT {$this->testField} FROM {$this->testTable}");
-        $this->assertInstanceOf('mysqli_result', $res);
-        $result = $res->fetch_assoc();
-        $this->assertEquals('foo', $result[$this->testField]);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminGetCharsetsReturnsArrayWithCharsets()
-    {
-        $columnsRes = $this->subject->admin_query('SHOW CHARACTER SET');
-        $result = $this->subject->admin_get_charsets();
-        $this->assertEquals(count($result), $columnsRes->num_rows);
-
-        /** @var array $row */
-        while (($row = $columnsRes->fetch_assoc())) {
-            $this->assertArrayHasKey($row['Charset'], $result);
-        }
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminGetKeysReturnIndexKeysOfTable()
-    {
-        $result = $this->subject->admin_get_keys($this->testTable);
-        $this->assertEquals('id', $result[0]['Column_name']);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminGetFieldsReturnFieldInformationsForTable()
-    {
-        $result = $this->subject->admin_get_fields($this->testTable);
-        $this->assertArrayHasKey('id', $result);
-        $this->assertArrayHasKey($this->testField, $result);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminGetTablesReturnAllTablesFromDatabase()
-    {
-        $result = $this->subject->admin_get_tables();
-        $this->assertArrayHasKey('tt_content', $result);
-        $this->assertArrayHasKey('pages', $result);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function adminGetDbsReturnsAllDatabases()
-    {
-        /** @noinspection SqlResolve */
-        $databases = $this->subject->admin_query('SELECT SCHEMA_NAME FROM information_schema.SCHEMATA');
-        $result = $this->subject->admin_get_dbs();
-        $this->assertSame(count($result), $databases->num_rows);
-
-        $i = 0;
-        while ($database = $databases->fetch_assoc()) {
-            $this->assertSame($database['SCHEMA_NAME'], $result[$i]);
-            $i++;
-        }
-    }
-
-    /**
-     * Data Provider for sqlNumRowsReturnsCorrectAmountOfRows()
-     *
-     * @see sqlNumRowsReturnsCorrectAmountOfRows()
-     *
-     * @return array
-     */
-    public function sqlNumRowsReturnsCorrectAmountOfRowsProvider()
-    {
-        $sql1 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'";
-        $sql2 = "SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz' OR {$this->testField}='bar'";
-        $sql3 = "SELECT * FROM {$this->testTable} WHERE {$this->testField} IN ('baz', 'bar', 'foo')";
-
-        return [
-            'One result' => [$sql1, 1],
-            'Two results' => [$sql2, 2],
-            'Three results' => [$sql3, 3],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider sqlNumRowsReturnsCorrectAmountOfRowsProvider
-     *
-     * @param string $sql
-     * @param string $expectedResult
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlNumRowsReturnsCorrectAmountOfRows($sql, $expectedResult)
-    {
-        $this->assertTrue(
-            $this->subject->admin_query(
-                "INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('foo'), ('bar'), ('baz')"
-            )
-        );
-
-        $res = $this->subject->admin_query($sql);
-        $numRows = $this->subject->sql_num_rows($res);
-        $this->assertSame($expectedResult, $numRows);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlNumRowsReturnsFalse()
-    {
-        $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE test='baz'");
-        $numRows = $this->subject->sql_num_rows($res);
-        $this->assertFalse($numRows);
-    }
-
-    /**
-     * Prepares the test table for the fetch* Tests
-     */
-    protected function prepareTableForFetchTests()
-    {
-        $this->assertTrue(
-            $this->subject->sql_query(
-                "ALTER TABLE {$this->testTable} " .
-                'ADD name mediumblob, ' .
-                'ADD deleted int, ' .
-                'ADD street varchar(100), ' .
-                'ADD city varchar(50), ' .
-                'ADD country varchar(100)'
-            )
-        );
-
-        $this->assertTrue(
-            $this->subject->admin_query(
-                "INSERT INTO {$this->testTable} (name,street,city,country,deleted) VALUES " .
-                "('Mr. Smith','Oakland Road','Los Angeles','USA',0)," .
-                "('Ms. Smith','Oakland Road','Los Angeles','USA',0)," .
-                "('Alice im Wunderland','Große Straße','Königreich der Herzen','Wunderland',0)," .
-                "('Agent Smith','Unbekannt','Unbekannt','Matrix',1)"
-            )
-        );
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlFetchAssocReturnsAssocArray()
-    {
-        $this->prepareTableForFetchTests();
-
-        $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
-        $expectedResult = [
-            [
-                'id' => '1',
-                $this->testField => null,
-                $this->anotherTestField => null,
-                'name' => 'Mr. Smith',
-                'deleted' => '0',
-                'street' => 'Oakland Road',
-                'city' => 'Los Angeles',
-                'country' => 'USA',
-            ],
-            [
-                'id' => '2',
-                $this->testField => null,
-                $this->anotherTestField => null,
-                'name' => 'Ms. Smith',
-                'deleted' => '0',
-                'street' => 'Oakland Road',
-                'city' => 'Los Angeles',
-                'country' => 'USA',
-            ],
-            [
-                'id' => '3',
-                $this->testField => null,
-                $this->anotherTestField => null,
-                'name' => 'Alice im Wunderland',
-                'deleted' => '0',
-                'street' => 'Große Straße',
-                'city' => 'Königreich der Herzen',
-                'country' => 'Wunderland',
-            ],
-            [
-                'id' => '4',
-                $this->testField => null,
-                $this->anotherTestField => null,
-                'name' => 'Agent Smith',
-                'deleted' => '1',
-                'street' => 'Unbekannt',
-                'city' => 'Unbekannt',
-                'country' => 'Matrix',
-            ],
-        ];
-        $i = 0;
-        while ($row = $this->subject->sql_fetch_assoc($res)) {
-            $this->assertSame($expectedResult[$i], $row);
-            $i++;
-        }
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlFetchRowReturnsNumericArray()
-    {
-        $this->prepareTableForFetchTests();
-        $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} ORDER BY id");
-        $expectedResult = [
-            ['1', null, null, 'Mr. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
-            ['2', null, null, 'Ms. Smith', '0', 'Oakland Road', 'Los Angeles', 'USA'],
-            ['3', null, null, 'Alice im Wunderland', '0', 'Große Straße', 'Königreich der Herzen', 'Wunderland'],
-            ['4', null, null, 'Agent Smith', '1', 'Unbekannt', 'Unbekannt', 'Matrix'],
-        ];
-        $i = 0;
-        while ($row = $this->subject->sql_fetch_row($res)) {
-            $this->assertSame($expectedResult[$i], $row);
-            $i++;
-        }
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlFreeResultReturnsFalseOnFailure()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
-        );
-        $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}=baz");
-        $this->assertFalse($this->subject->sql_free_result($res));
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function sqlFreeResultReturnsTrueOnSuccess()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('baz')")
-        );
-        $res = $this->subject->admin_query("SELECT * FROM {$this->testTable} WHERE {$this->testField}='baz'");
-        $this->assertTrue($this->subject->sql_free_result($res));
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Tests/Functional/Database/PreparedStatementTest.php b/typo3/sysext/typo3db_legacy/Tests/Functional/Database/PreparedStatementTest.php
deleted file mode 100644 (file)
index 3a4ba58..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Tests\Functional\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection;
-
-/**
- * Test case for \TYPO3\CMS\Core\Database\PreparedStatement
- */
-class PreparedStatementTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
-{
-    /**
-     * @var array
-     */
-    protected $coreExtensionsToLoad = ['typo3db_legacy'];
-
-    /**
-     * @var DatabaseConnection
-     */
-    protected $subject = null;
-
-    /**
-     * @var string
-     */
-    protected $testTable = 'test_database_connection';
-
-    /**
-     * @var string
-     */
-    protected $testField = 'test_field';
-
-    /**
-     * @var string
-     */
-    protected $anotherTestField = 'another_test_field';
-
-    /**
-     * Set the test up
-     */
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->subject = $GLOBALS['TYPO3_DB'];
-        $this->subject->sql_query(
-            "CREATE TABLE {$this->testTable} (" .
-            '   id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,' .
-            "   {$this->testField} MEDIUMBLOB," .
-            "   {$this->anotherTestField} MEDIUMBLOB," .
-            '   PRIMARY KEY (id)' .
-            ') ENGINE=MyISAM DEFAULT CHARSET=utf8;'
-        );
-    }
-
-    /**
-     * Tear the test down
-     */
-    protected function tearDown()
-    {
-        $this->subject->sql_query("DROP TABLE {$this->testTable};");
-        unset($this->subject);
-    }
-
-    /**
-     * @test
-     *
-     * @group not-postgres
-     * @group not-mssql
-     */
-    public function prepareSelectQueryCreateValidQuery()
-    {
-        $this->assertTrue(
-            $this->subject->admin_query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('aTestValue')")
-        );
-        $preparedQuery = $this->subject->prepare_SELECTquery(
-            "{$this->testField},{$this->anotherTestField}",
-            $this->testTable,
-            'id=:id',
-            '',
-            '',
-            '',
-            [':id' => 1]
-        );
-        $preparedQuery->execute();
-        $result = $preparedQuery->fetch();
-        $expectedResult = [
-            $this->testField => 'aTestValue',
-            $this->anotherTestField => null,
-        ];
-        $this->assertSame($expectedResult, $result);
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Tests/Unit/Database/DatabaseConnectionTest.php b/typo3/sysext/typo3db_legacy/Tests/Unit/Database/DatabaseConnectionTest.php
deleted file mode 100644 (file)
index 7c0bd36..0000000
+++ /dev/null
@@ -1,753 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Tests\Unit\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection;
-use TYPO3\TestingFramework\Core\AccessibleObjectInterface;
-
-/**
- * Test case
- */
-class DatabaseConnectionTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
-{
-    /**
-     * @var DatabaseConnection
-     */
-    protected $subject;
-    /**
-     * @var string
-     */
-    protected $testTable = 'test_database_connection';
-
-    /**
-     * @var string
-     */
-    protected $testField = 'test_field';
-
-    /**
-     * @var string
-     */
-    protected $anotherTestField = 'another_test_field';
-
-    /**
-     * Set the test up
-     */
-    protected function setUp()
-    {
-        parent::setUp();
-        $this->subject = $this->getAccessibleMock(DatabaseConnection::class, ['dummy'], [], '', false);
-        $this->subject->_set('databaseName', 'typo3_test');
-    }
-
-    //////////////////////////////////////////////////
-    // Write/Read tests for charsets and binaries
-    //////////////////////////////////////////////////
-
-    /**
-     * @test
-     */
-    public function storedFullAsciiRangeCallsLinkObjectWithGivenData()
-    {
-        $binaryString = '';
-        for ($i = 0; $i < 256; $i++) {
-            $binaryString .= chr($i);
-        }
-
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject
-            ->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return $data;
-            }));
-        $mysqliProphecy = $this->prophesize(\mysqli::class);
-        $mysqliProphecy->query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ({$binaryString})")
-            ->shouldBeCalled();
-        $subject->_set('link', $mysqliProphecy->reveal());
-
-        $subject->exec_INSERTquery($this->testTable, [$this->testField => $binaryString]);
-    }
-
-    /**
-     * @test
-     * @requires function gzcompress
-     */
-    public function storedGzipCompressedDataReturnsSameData()
-    {
-        $testStringWithBinary = gzcompress('sdfkljer4587');
-
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject
-            ->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return $data;
-            }));
-        $mysqliProphecy = $this->prophesize(\mysqli::class);
-        $mysqliProphecy->query("INSERT INTO {$this->testTable} ({$this->testField}) VALUES ({$testStringWithBinary})")
-            ->shouldBeCalled();
-        $subject->_set('link', $mysqliProphecy->reveal());
-
-        $subject->exec_INSERTquery($this->testTable, [$this->testField => $testStringWithBinary]);
-    }
-
-    ////////////////////////////////
-    // Tests concerning listQuery
-    ////////////////////////////////
-
-    /**
-     * @test
-     * @see http://forge.typo3.org/issues/23253
-     */
-    public function listQueryWithIntegerCommaAsValue()
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['quoteStr'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject
-            ->expects($this->any())
-            ->method('quoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return $data;
-            }));
-        // Note: 44 = ord(',')
-        $this->assertEquals($subject->listQuery('dummy', 44, 'table'), $subject->listQuery('dummy', '44', 'table'));
-    }
-
-    /**
-     * @test
-     */
-    public function listQueryThrowsExceptionIfValueContainsComma()
-    {
-        $this->expectException(\InvalidArgumentException::class);
-        $this->expectExceptionCode(1294585862);
-
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['quoteStr'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject->listQuery('aField', 'foo,bar', 'aTable');
-    }
-
-    ////////////////////////////////
-    // Tests concerning searchQuery
-    ////////////////////////////////
-
-    /**
-     * Data provider for searchQueryCreatesQuery
-     *
-     * @return array
-     */
-    public function searchQueryDataProvider()
-    {
-        return [
-            'One search word in one field' => [
-                '(pages.title LIKE \'%TYPO3%\')',
-                ['TYPO3'],
-                ['title'],
-                'pages',
-                'AND',
-            ],
-            'One search word with special chars (for like)' => [
-                '(pages.title LIKE \'%TYPO3\\_100\\%%\')',
-                ['TYPO3_100%'],
-                ['title'],
-                'pages',
-                'AND',
-            ],
-            'One search word in multiple fields' => [
-                "(pages.title LIKE '%TYPO3%' OR pages.keyword LIKE '%TYPO3%' OR pages.description LIKE '%TYPO3%')",
-                ['TYPO3'],
-                ['title', 'keyword', 'description'],
-                'pages',
-                'AND',
-            ],
-            'Multiple search words in one field with AND constraint' => [
-                "(pages.title LIKE '%TYPO3%') AND (pages.title LIKE '%is%') AND (pages.title LIKE '%great%')",
-                ['TYPO3', 'is', 'great'],
-                ['title'],
-                'pages',
-                'AND',
-            ],
-            'Multiple search words in one field with OR constraint' => [
-                "(pages.title LIKE '%TYPO3%') OR (pages.title LIKE '%is%') OR (pages.title LIKE '%great%')",
-                ['TYPO3', 'is', 'great'],
-                ['title'],
-                'pages',
-                'OR',
-            ],
-            'Multiple search words in multiple fields with AND constraint' => [
-                "(pages.title LIKE '%TYPO3%' OR pages.keywords LIKE '%TYPO3%' OR pages.description LIKE '%TYPO3%') " .
-                "AND (pages.title LIKE '%is%' OR pages.keywords LIKE '%is%' OR pages.description LIKE '%is%') " .
-                "AND (pages.title LIKE '%great%' OR pages.keywords LIKE '%great%' OR pages.description LIKE '%great%')",
-                ['TYPO3', 'is', 'great'],
-                ['title', 'keywords', 'description'],
-                'pages',
-                'AND',
-            ],
-            'Multiple search words in multiple fields with OR constraint' => [
-                "(pages.title LIKE '%TYPO3%' OR pages.keywords LIKE '%TYPO3%' OR pages.description LIKE '%TYPO3%') " .
-                "OR (pages.title LIKE '%is%' OR pages.keywords LIKE '%is%' OR pages.description LIKE '%is%') " .
-                "OR (pages.title LIKE '%great%' OR pages.keywords LIKE '%great%' OR pages.description LIKE '%great%')",
-                ['TYPO3', 'is', 'great'],
-                ['title', 'keywords', 'description'],
-                'pages',
-                'OR',
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider searchQueryDataProvider
-     * @param string $expectedResult
-     * @param array $searchWords
-     * @param array $fields
-     * @param string $table
-     * @param string $constraint
-     */
-    public function searchQueryCreatesQuery($expectedResult, array $searchWords, array $fields, $table, $constraint)
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
-        $subject = $this->getMockBuilder(DatabaseConnection::class)
-            ->setMethods(['quoteStr'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $subject
-            ->expects($this->any())
-            ->method('quoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return $data;
-            }));
-
-        $this->assertSame($expectedResult, $subject->searchQuery($searchWords, $fields, $table, $constraint));
-    }
-
-    /////////////////////////////////////////////////
-    // Tests concerning escapeStringForLikeComparison
-    /////////////////////////////////////////////////
-
-    /**
-     * @test
-     */
-    public function escapeStringForLikeComparison()
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
-        $subject = $this->getMockBuilder(DatabaseConnection::class)
-            ->setMethods(['dummy'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->assertEquals('foo\\_bar\\%', $subject->escapeStrForLike('foo_bar%', 'table'));
-    }
-
-    /////////////////////////////////////////////////
-    // Tests concerning stripOrderByForOrderByKeyword
-    /////////////////////////////////////////////////
-
-    /**
-     * Data Provider for stripGroupByForGroupByKeyword()
-     *
-     * @see stripOrderByForOrderByKeyword()
-     * @return array
-     */
-    public function stripOrderByForOrderByKeywordDataProvider()
-    {
-        return [
-            'single ORDER BY' => [
-                'ORDER BY name, tstamp',
-                'name, tstamp'
-            ],
-            'single ORDER BY in lower case' => [
-                'order by name, tstamp',
-                'name, tstamp'
-            ],
-            'ORDER BY with additional space behind' => [
-                'ORDER BY  name, tstamp',
-                'name, tstamp'
-            ],
-            'ORDER BY without space between the words' => [
-                'ORDERBY name, tstamp',
-                'name, tstamp'
-            ],
-            'ORDER BY added twice' => [
-                'ORDER BY ORDER BY name, tstamp',
-                'name, tstamp'
-            ],
-            'ORDER BY added twice without spaces in the first occurrence' => [
-                'ORDERBY ORDER BY  name, tstamp',
-                'name, tstamp',
-            ],
-            'ORDER BY added twice without spaces in the second occurrence' => [
-                'ORDER BYORDERBY name, tstamp',
-                'name, tstamp',
-            ],
-            'ORDER BY added twice without spaces' => [
-                'ORDERBYORDERBY name, tstamp',
-                'name, tstamp'
-            ],
-            'ORDER BY added twice without spaces afterwards' => [
-                'ORDERBYORDERBYname, tstamp',
-                'name, tstamp'
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider stripOrderByForOrderByKeywordDataProvider
-     * @param string $orderByClause The clause to test
-     * @param string $expectedResult The expected result
-     */
-    public function stripOrderByForOrderByKeyword($orderByClause, $expectedResult)
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
-        $subject = $this->getMockBuilder(DatabaseConnection::class)
-            ->setMethods(['dummy'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $strippedQuery = $subject->stripOrderBy($orderByClause);
-        $this->assertEquals($expectedResult, $strippedQuery);
-    }
-
-    /////////////////////////////////////////////////
-    // Tests concerning stripGroupByForGroupByKeyword
-    /////////////////////////////////////////////////
-
-    /**
-     * Data Provider for stripGroupByForGroupByKeyword()
-     *
-     * @see stripGroupByForGroupByKeyword()
-     * @return array
-     */
-    public function stripGroupByForGroupByKeywordDataProvider()
-    {
-        return [
-            'single GROUP BY' => [
-                'GROUP BY name, tstamp',
-                'name, tstamp'
-            ],
-            'single GROUP BY in lower case' => [
-                'group by name, tstamp',
-                'name, tstamp'
-            ],
-            'GROUP BY with additional space behind' => [
-                'GROUP BY  name, tstamp',
-                'name, tstamp'
-            ],
-            'GROUP BY without space between the words' => [
-                'GROUPBY name, tstamp',
-                'name, tstamp'
-            ],
-            'GROUP BY added twice' => [
-                'GROUP BY GROUP BY name, tstamp',
-                'name, tstamp'
-            ],
-            'GROUP BY added twice without spaces in the first occurrence' => [
-                'GROUPBY GROUP BY  name, tstamp',
-                'name, tstamp',
-            ],
-            'GROUP BY added twice without spaces in the second occurrence' => [
-                'GROUP BYGROUPBY name, tstamp',
-                'name, tstamp',
-            ],
-            'GROUP BY added twice without spaces' => [
-                'GROUPBYGROUPBY name, tstamp',
-                'name, tstamp'
-            ],
-            'GROUP BY added twice without spaces afterwards' => [
-                'GROUPBYGROUPBYname, tstamp',
-                'name, tstamp'
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider stripGroupByForGroupByKeywordDataProvider
-     * @param string $groupByClause The clause to test
-     * @param string $expectedResult The expected result
-     */
-    public function stripGroupByForGroupByKeyword($groupByClause, $expectedResult)
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject $subject */
-        $subject = $this->getMockBuilder(DatabaseConnection::class)
-            ->setMethods(['dummy'])
-            ->disableOriginalConstructor()
-            ->getMock();
-        $strippedQuery = $subject->stripGroupBy($groupByClause);
-        $this->assertEquals($expectedResult, $strippedQuery);
-    }
-
-    /////////////////////////////////////////////////
-    // Tests concerning stripOrderByForOrderByKeyword
-    /////////////////////////////////////////////////
-
-    /**
-     * Data Provider for stripGroupByForGroupByKeyword()
-     *
-     * @see stripOrderByForOrderByKeyword()
-     * @return array
-     */
-    public function cleanIntArrayDataProvider()
-    {
-        return [
-            'simple array' => [
-                [1, 2, 3],
-                [1, 2, 3],
-            ],
-            'string array' => [
-                ['2', '4', '8'],
-                [2, 4, 8],
-            ],
-            'string array with letters #1' => [
-                ['3', '6letters', '12'],
-                [3, 6, 12],
-            ],
-            'string array with letters #2' => [
-                ['3', 'letters6', '12'],
-                [3, 0, 12],
-            ],
-            'string array with letters #3' => [
-                ['3', '6letters4', '12'],
-                [3, 6, 12],
-            ],
-            'associative array' => [
-                ['apples' => 3, 'bananas' => 4, 'kiwis' => 9],
-                ['apples' => 3, 'bananas' => 4, 'kiwis' => 9],
-            ],
-            'associative string array' => [
-                ['apples' => '1', 'bananas' => '5', 'kiwis' => '7'],
-                ['apples' => 1, 'bananas' => 5, 'kiwis' => 7],
-            ],
-            'associative string array with letters #1' => [
-                ['apples' => '1', 'bananas' => 'no5', 'kiwis' => '7'],
-                ['apples' => 1, 'bananas' => 0, 'kiwis' => 7],
-            ],
-            'associative string array with letters #2' => [
-                ['apples' => '1', 'bananas' => '5yes', 'kiwis' => '7'],
-                ['apples' => 1, 'bananas' => 5, 'kiwis' => 7],
-            ],
-            'associative string array with letters #3' => [
-                ['apples' => '1', 'bananas' => '5yes9', 'kiwis' => '7'],
-                ['apples' => 1, 'bananas' => 5, 'kiwis' => 7],
-            ],
-            'multidimensional associative array' => [
-                ['apples' => '1', 'bananas' => [3, 4], 'kiwis' => '7'],
-                // intval(array(...)) is 1
-                // But by specification "cleanIntArray" should only get used on one-dimensional arrays
-                ['apples' => 1, 'bananas' => 1, 'kiwis' => 7],
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider cleanIntArrayDataProvider
-     * @param array $exampleData The array to sanitize
-     * @param array $expectedResult The expected result
-     */
-    public function cleanIntArray($exampleData, $expectedResult)
-    {
-        $sanitizedArray = $this->subject->cleanIntArray($exampleData);
-        $this->assertEquals($expectedResult, $sanitizedArray);
-    }
-
-    /**
-     * @test
-     */
-    public function cleanIntListReturnsCleanedString()
-    {
-        $str = '234,-434,4.3,0, 1';
-        $result = $this->subject->cleanIntList($str);
-        $this->assertSame('234,-434,4,0,1', $result);
-    }
-
-    /**
-     * @test
-     */
-    public function sqlForSelectMmQuery()
-    {
-        $result = $this->subject->SELECT_mm_query(
-            '*',
-            'sys_category',
-            'sys_category_record_mm',
-            'tt_content',
-            'AND sys_category.uid = 1',
-            '',
-            'sys_category.title DESC'
-        );
-        $expected = 'SELECT * FROM sys_category,sys_category_record_mm,tt_content ' .
-            'WHERE sys_category.uid=sys_category_record_mm.uid_local ' .
-            'AND tt_content.uid=sys_category_record_mm.uid_foreign ' .
-            'AND sys_category.uid = 1 ORDER BY sys_category.title DESC';
-        $this->assertEquals($expected, $result);
-    }
-
-    /**
-     * Data provider for searchQueryCreatesQuery
-     *
-     * @return array
-     */
-    public function noQuoteForFullQuoteArrayDataProvider()
-    {
-        return [
-            'noQuote boolean false' => [
-                ['aField' => 'aValue', 'anotherField' => 'anotherValue'],
-                ['aField' => "'aValue'", 'anotherField' => "'anotherValue'"],
-                false,
-            ],
-            'noQuote boolean true' => [
-                ['aField' => 'aValue', 'anotherField' => 'anotherValue'],
-                ['aField' => 'aValue', 'anotherField' => 'anotherValue'],
-                true,
-            ],
-            'noQuote list of fields' => [
-                ['aField' => 'aValue', 'anotherField' => 'anotherValue'],
-                ['aField' => "'aValue'", 'anotherField' => 'anotherValue'],
-                'anotherField',
-            ],
-            'noQuote array of fields' => [
-                ['aField' => 'aValue', 'anotherField' => 'anotherValue'],
-                ['aField' => 'aValue', 'anotherField' => "'anotherValue'"],
-                ['aField'],
-            ],
-        ];
-    }
-
-    /**
-     * @test
-     * @param array $input
-     * @param array $expected
-     * @param bool|array|string $noQuote
-     * @dataProvider noQuoteForFullQuoteArrayDataProvider
-     */
-    public function noQuoteForFullQuoteArray(array $input, array $expected, $noQuote)
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getMockBuilder(DatabaseConnection::class)
-            ->setMethods(['fullQuoteStr'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $subject
-            ->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return '\'' . (string)$data . '\'';
-            }));
-        $this->assertSame($expected, $subject->fullQuoteArray($input, 'aTable', $noQuote));
-    }
-
-    /**
-     * @test
-     */
-    public function sqlSelectDbReturnsTrue()
-    {
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['dummy'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject->_set('databaseName', $this->testTable);
-
-        $mysqliProphecy = $this->prophesize(\mysqli::class);
-        $mysqliProphecy->select_db($this->testTable)->shouldBeCalled()->willReturn(true);
-        $subject->_set('link', $mysqliProphecy->reveal());
-
-        $this->assertTrue($subject->sql_select_db());
-    }
-
-    /**
-     * @test
-     */
-    public function sqlSelectDbReturnsFalse()
-    {
-        $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel'] = GeneralUtility::SYSLOG_SEVERITY_WARNING;
-
-        /** @var DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject|AccessibleObjectInterface $subject */
-        $subject = $this->getAccessibleMock(DatabaseConnection::class, ['sql_error'], [], '', false);
-        $subject->_set('isConnected', true);
-        $subject->_set('databaseName', $this->testTable);
-        $subject->expects($this->any())->method('sql_error')->will($this->returnValue(''));
-
-        $mysqliProphecy = $this->prophesize(\mysqli::class);
-        $mysqliProphecy->select_db($this->testTable)->shouldBeCalled()->willReturn(false);
-        $subject->_set('link', $mysqliProphecy->reveal());
-
-        $this->assertFalse($subject->sql_select_db());
-    }
-
-    /**
-     * @test
-     */
-    public function insertQueryCreateValidQuery()
-    {
-        $this->subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $this->subject->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return '\'' . (string)$data . '\'';
-            }));
-
-        $fieldValues = [$this->testField => 'Foo'];
-        $queryExpected = "INSERT INTO {$this->testTable} ({$this->testField}) VALUES ('Foo')";
-        $queryGenerated = $this->subject->INSERTquery($this->testTable, $fieldValues);
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function insertQueryCreateValidQueryFromMultipleValues()
-    {
-        $this->subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $this->subject->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return '\'' . (string)$data . '\'';
-            }));
-        $fieldValues = [
-            $this->testField => 'Foo',
-            $this->anotherTestField => 'Bar',
-        ];
-        $queryExpected = "INSERT INTO {$this->testTable} ({$this->testField},{$this->anotherTestField}) " .
-            "VALUES ('Foo','Bar')";
-        $queryGenerated = $this->subject->INSERTquery($this->testTable, $fieldValues);
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function insertMultipleRowsCreateValidQuery()
-    {
-        $this->subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $this->subject->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return '\'' . (string)$data . '\'';
-            }));
-        $fields = [$this->testField, $this->anotherTestField];
-        $values = [
-            ['Foo', 100],
-            ['Bar', 200],
-            ['Baz', 300],
-        ];
-        $queryExpected = "INSERT INTO {$this->testTable} ({$this->testField}, {$this->anotherTestField}) " .
-            "VALUES ('Foo', '100'), ('Bar', '200'), ('Baz', '300')";
-        $queryGenerated = $this->subject->INSERTmultipleRows($this->testTable, $fields, $values);
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function updateQueryCreateValidQuery()
-    {
-        $this->subject = $this->getAccessibleMock(DatabaseConnection::class, ['fullQuoteStr'], [], '', false);
-        $this->subject->expects($this->any())
-            ->method('fullQuoteStr')
-            ->will($this->returnCallback(function ($data) {
-                return '\'' . (string)$data . '\'';
-            }));
-
-        $fieldsValues = [$this->testField => 'aTestValue'];
-        $queryExpected = "UPDATE {$this->testTable} SET {$this->testField}='aTestValue' WHERE id=1";
-        $queryGenerated = $this->subject->UPDATEquery($this->testTable, 'id=1', $fieldsValues);
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function deleteQueryCreateValidQuery()
-    {
-        $queryExpected = "DELETE FROM {$this->testTable} WHERE id=1";
-        $queryGenerated = $this->subject->DELETEquery($this->testTable, 'id=1');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectQueryCreateValidQuery()
-    {
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable} WHERE id=1";
-        $queryGenerated = $this->subject->SELECTquery($this->testField, $this->testTable, 'id=1');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectQueryCreateValidQueryWithEmptyWhereClause()
-    {
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable}";
-        $queryGenerated = $this->subject->SELECTquery($this->testField, $this->testTable, '');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectQueryCreateValidQueryWithGroupByClause()
-    {
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable} WHERE id=1 GROUP BY id";
-        $queryGenerated = $this->subject->SELECTquery($this->testField, $this->testTable, 'id=1', 'id');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectQueryCreateValidQueryWithOrderByClause()
-    {
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable} WHERE id=1 ORDER BY id";
-        $queryGenerated = $this->subject->SELECTquery($this->testField, $this->testTable, 'id=1', '', 'id');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectQueryCreateValidQueryWithLimitClause()
-    {
-        $queryGenerated = $this->subject->SELECTquery($this->testField, $this->testTable, 'id=1', '', '', '1,2');
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable} WHERE id=1 LIMIT 1,2";
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function selectSubQueryCreateValidQuery()
-    {
-        $queryExpected = "SELECT {$this->testField} FROM {$this->testTable} WHERE id=1";
-        $queryGenerated = $this->subject->SELECTsubquery($this->testField, $this->testTable, 'id=1');
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-
-    /**
-     * @test
-     */
-    public function truncateQueryCreateValidQuery()
-    {
-        $queryExpected = "TRUNCATE TABLE {$this->testTable}";
-        $queryGenerated = $this->subject->TRUNCATEquery($this->testTable);
-        $this->assertSame($queryExpected, $queryGenerated);
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/Tests/Unit/Database/PreparedStatementTest.php b/typo3/sysext/typo3db_legacy/Tests/Unit/Database/PreparedStatementTest.php
deleted file mode 100644 (file)
index e8de31e..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-<?php
-namespace TYPO3\CMS\Typo3DbLegacy\Tests\Unit\Database;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection;
-use TYPO3\CMS\Typo3DbLegacy\Database\PreparedStatement;
-
-/**
- * Test case
- */
-class PreparedStatementTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
-{
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|DatabaseConnection
-     */
-    protected $databaseStub;
-
-    /**
-     * Create a new database mock object for every test
-     * and backup the original global database object.
-     */
-    protected function setUp()
-    {
-        $this->databaseStub = $this->setUpAndReturnDatabaseStub();
-    }
-
-    //////////////////////
-    // Utility functions
-    //////////////////////
-    /**
-     * Set up the stub to be able to get the result of the prepared statement.
-     *
-     * @return \PHPUnit_Framework_MockObject_MockObject
-     */
-    private function setUpAndReturnDatabaseStub()
-    {
-        $GLOBALS['TYPO3_DB'] = $this->getAccessibleMock(
-            DatabaseConnection::class,
-            ['prepare_PREPAREDquery'],
-            [],
-            '',
-            false,
-            false
-        );
-
-        return $GLOBALS['TYPO3_DB'];
-    }
-
-    /**
-     * Create an object fo the subject to be tested.
-     *
-     * @param string $query
-     * @return PreparedStatement
-     */
-    private function createPreparedStatement($query)
-    {
-        return new PreparedStatement($query, 'pages');
-    }
-
-    ////////////////////////////////////
-    // Tests for the utility functions
-    ////////////////////////////////////
-
-    /**
-     * @test
-     */
-    public function setUpAndReturnDatabaseStubReturnsMockObjectOfDatabaseConnection()
-    {
-        $this->assertTrue($this->setUpAndReturnDatabaseStub() instanceof DatabaseConnection);
-    }
-
-    /**
-     * @test
-     */
-    public function createPreparedStatementReturnsInstanceOfPreparedStatementClass()
-    {
-        $this->assertTrue($this->createPreparedStatement('dummy') instanceof PreparedStatement);
-    }
-
-    ///////////////////////////////////////
-    // Tests for \TYPO3\CMS\Core\Database\PreparedStatement
-    ///////////////////////////////////////
-    /**
-     * Data Provider for two tests, providing sample queries, parameters and expected result queries.
-     *
-     * @see parametersAreReplacedInQueryByCallingExecute
-     * @see parametersAreReplacedInQueryWhenBoundWithBindValues
-     * @return array
-     */
-    public function parametersAndQueriesDataProvider()
-    {
-        return [
-            'one named integer parameter' => [
-                'SELECT * FROM pages WHERE pid=:pid',
-                [':pid' => 1],
-                'SELECT * FROM pages WHERE pid=?'
-            ],
-            'one unnamed integer parameter' => [
-                'SELECT * FROM pages WHERE pid=?',
-                [1],
-                'SELECT * FROM pages WHERE pid=?'
-            ],
-            'one named integer parameter is replaced multiple times' => [
-                'SELECT * FROM pages WHERE pid=:pid OR uid=:pid',
-                [':pid' => 1],
-                'SELECT * FROM pages WHERE pid=? OR uid=?'
-            ],
-            'two named integer parameters are replaced' => [
-                'SELECT * FROM pages WHERE pid=:pid OR uid=:uid',
-                [':pid' => 1, ':uid' => 10],
-                'SELECT * FROM pages WHERE pid=? OR uid=?'
-            ],
-            'two unnamed integer parameters are replaced' => [
-                'SELECT * FROM pages WHERE pid=? OR uid=?',
-                [1, 1],
-                'SELECT * FROM pages WHERE pid=? OR uid=?'
-            ],
-        ];
-    }
-
-    /**
-     * Checking if calling execute() with parameters, they are
-     * properly replaced in the query.
-     *
-     * @test
-     * @dataProvider parametersAndQueriesDataProvider
-     * @param string $query Query with unreplaced markers
-     * @param array  $parameters Array of parameters to be replaced in the query
-     * @param string $expectedResult Query with all markers replaced
-     */
-    public function parametersAreReplacedByQuestionMarkInQueryByCallingExecute($query, $parameters, $expectedResult)
-    {
-        $statement = $this->createPreparedStatement($query);
-        $this->databaseStub->expects($this->any())
-            ->method('prepare_PREPAREDquery')
-            ->with($this->equalTo($expectedResult));
-        $statement->execute($parameters);
-    }
-
-    /**
-     * Checking if parameters bound to the statement by bindValues()
-     * are properly replaced in the query.
-     *
-     * @test
-     * @dataProvider parametersAndQueriesDataProvider
-     * @param string $query Query with unreplaced markers
-     * @param array  $parameters Array of parameters to be replaced in the query
-     * @param string $expectedResult Query with all markers replaced
-     */
-    public function parametersAreReplacedInQueryWhenBoundWithBindValues($query, $parameters, $expectedResult)
-    {
-        $statement = $this->createPreparedStatement($query);
-        $this->databaseStub->expects($this->any())
-            ->method('prepare_PREPAREDquery')
-            ->with($this->equalTo($expectedResult));
-        $statement->bindValues($parameters);
-        $statement->execute();
-    }
-
-    /**
-     * Data Provider with invalid parameters.
-     *
-     * @see invalidParameterTypesPassedToBindValueThrowsException
-     * @return array
-     */
-    public function invalidParameterTypesPassedToBindValueThrowsExceptionDataProvider()
-    {
-        return [
-            'integer passed with param type NULL' => [
-                1,
-                PreparedStatement::PARAM_NULL,
-                1282489834
-            ],
-            'string passed with param type NULL' => [
-                '1',
-                PreparedStatement::PARAM_NULL,
-                1282489834
-            ],
-            'bool passed with param type NULL' => [
-                true,
-                PreparedStatement::PARAM_NULL,
-                1282489834
-            ],
-            'NULL passed with param type INT' => [
-                null,
-                PreparedStatement::PARAM_INT,
-                1281868686
-            ],
-            'string passed with param type INT' => [
-                '1',
-                PreparedStatement::PARAM_INT,
-                1281868686
-            ],
-            'bool passed with param type INT' => [
-                true,
-                PreparedStatement::PARAM_INT,
-                1281868686
-            ],
-            'NULL passed with param type BOOL' => [
-                null,
-                PreparedStatement::PARAM_BOOL,
-                1281868687
-            ],
-            'string passed with param type BOOL' => [
-                '1',
-                PreparedStatement::PARAM_BOOL,
-                1281868687
-            ],
-            'integer passed with param type BOOL' => [
-                1,
-                PreparedStatement::PARAM_BOOL,
-                1281868687
-            ]
-        ];
-    }
-
-    /**
-     * Checking if an exception is thrown if invalid parameters are
-     * provided vor bindValue().
-     *
-     * @test
-     * @dataProvider invalidParameterTypesPassedToBindValueThrowsExceptionDataProvider
-     * @param mixed $parameter Parameter to be replaced in the query
-     * @param int $type Type of the parameter value
-     * @param int $exceptionCode Expected exception code
-     */
-    public function invalidParameterTypesPassedToBindValueThrowsException($parameter, $type, $exceptionCode)
-    {
-        $this->expectException(\InvalidArgumentException::class);
-        $this->expectExceptionCode($exceptionCode);
-
-        $statement = $this->createPreparedStatement('');
-        $statement->bindValue(1, $parameter, $type);
-    }
-
-    /**
-     * Data Provider for invalid marker names.
-     *
-     * @see passingInvalidMarkersThrowsExeption
-     * @return array
-     */
-    public function passingInvalidMarkersThrowsExceptionDataProvider()
-    {
-        return [
-            'using other prefix than colon' => [
-                /** @lang text */
-                'SELECT * FROM pages WHERE pid=#pid',
-                ['#pid' => 1]
-            ],
-            'using non alphanumerical character' => [
-                /** @lang text */
-                'SELECT * FROM pages WHERE title=:stra≠e',
-                [':stra≠e' => 1]
-            ],
-            'no colon used' => [
-                /** @lang text */
-                'SELECT * FROM pages WHERE pid=pid',
-                ['pid' => 1]
-            ],
-            'colon at the end' => [
-                /** @lang text */
-                'SELECT * FROM pages WHERE pid=pid:',
-                ['pid:' => 1]
-            ],
-            'colon without alphanumerical character' => [
-                /** @lang text */
-                'SELECT * FROM pages WHERE pid=:',
-                [':' => 1]
-            ]
-        ];
-    }
-
-    /**
-     * Checks if an exception is thrown, if parameter have invalid marker named.
-     *
-     * @test
-     * @dataProvider passingInvalidMarkersThrowsExceptionDataProvider
-     * @param string $query Query with unreplaced markers
-     * @param array  $parameters Array of parameters to be replaced in the query
-     */
-    public function passingInvalidMarkersThrowsException($query, $parameters)
-    {
-        $this->expectException(\InvalidArgumentException::class);
-        $this->expectExceptionCode(1395055513);
-
-        $statement = $this->createPreparedStatement($query);
-        $statement->bindValues($parameters);
-    }
-}
diff --git a/typo3/sysext/typo3db_legacy/composer.json b/typo3/sysext/typo3db_legacy/composer.json
deleted file mode 100644 (file)
index 0452ec5..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "name": "typo3/cms-typo3db-legacy",
-  "type": "typo3-cms-framework",
-       "description": "TYPO3_DB compatibility layer for TYPO3 v9.x",
-       "homepage": "https://typo3.org",
-       "license": ["GPL-2.0+"],
-
-       "require": {
-               "typo3/cms-core": "*"
-       },
-       "replace": {
-               "typo3db_legacy": "*"
-       },
-       "extra": {
-               "typo3/class-alias-loader": {
-                       "class-alias-maps": [
-                               "Migrations/Code/ClassAliasMap.php"
-                       ]
-               }
-       },
-       "autoload": {
-               "psr-4": {
-                       "TYPO3\\CMS\\Typo3DbLegacy\\": "Classes/"
-               }
-       }
-}
\ No newline at end of file
diff --git a/typo3/sysext/typo3db_legacy/ext_emconf.php b/typo3/sysext/typo3db_legacy/ext_emconf.php
deleted file mode 100644 (file)
index 44dd65f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-$EM_CONF[$_EXTKEY] = [
-    'title' => 'TYPO3_DB compatibility layer for TYPO3 v9.x',
-    'description' => 'Provides $GLOBALS[\'TYPO3_DB\'] as backwards-compatibility with legacy functionality for extensions that haven\'t fully migrated to doctrine yet.',
-    'category' => 'be',
-    'state' => 'stable',
-    'uploadfolder' => 0,
-    'createDirs' => '',
-    'clearCacheOnLoad' => 0,
-    'author' => 'TYPO3 CMS Team',
-    'author_email' => '',
-    'author_company' => '',
-    'version' => '9.0.0',
-    'constraints' => [
-        'depends' => [
-            'typo3' => '9.0.0-9.6.99',
-            'backend' => '9.0.0-9.6.99',
-        ],
-    ],
-];
diff --git a/typo3/sysext/typo3db_legacy/ext_localconf.php b/typo3/sysext/typo3db_legacy/ext_localconf.php
deleted file mode 100644 (file)
index 2fd3a52..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-defined('TYPO3_MODE') or die();
-
-call_user_func(function () {
-    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\TYPO3\CMS\Typo3DbLegacy\Updates\DbalAndAdodbExtractionUpdate::class]
-        = \TYPO3\CMS\Typo3DbLegacy\Updates\DbalAndAdodbExtractionUpdate::class;
-
-    // Initialize database connection in $GLOBALS and connect
-    $databaseConnection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Typo3DbLegacy\Database\DatabaseConnection::class);
-    $databaseConnection->setDatabaseName(
-        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname'] ?? ''
-    );
-    $databaseConnection->setDatabaseUsername(
-        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user'] ?? ''
-    );
-    $databaseConnection->setDatabasePassword(
-        $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['password'] ?? ''
-    );
-
-    $databaseHost = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'] ?? '';
-    if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['port'])) {
-        $databaseConnection->setDatabasePort($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['port']);
-    } elseif (strpos($databaseHost, ':') > 0) {
-        // @TODO: Find a way to handle this case in the install tool and drop this
-        list($databaseHost, $databasePort) = explode(':', $databaseHost);
-        $databaseConnection->setDatabasePort($databasePort);
-    }
-    if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['unix_socket'])) {
-        $databaseConnection->setDatabaseSocket(
-            $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['unix_socket']
-        );
-    }
-    $databaseConnection->setDatabaseHost($databaseHost);
-
-    $databaseConnection->debugOutput = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sqlDebug'];
-
-    if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['persistentConnection'])
-        && $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['persistentConnection']
-    ) {
-        $databaseConnection->setPersistentDatabaseConnection(true);
-    }
-
-    $isDatabaseHostLocalHost = in_array($databaseHost, ['localhost', '127.0.0.1', '::1'], true);
-    if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['driverOptions'])
-        && $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['driverOptions'] & MYSQLI_CLIENT_COMPRESS
-        && !$isDatabaseHostLocalHost
-    ) {
-        $databaseConnection->setConnectionCompression(true);
-    }
-
-    if (!empty($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['initCommands'])) {
-        $commandsAfterConnect = TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(
-            LF,
-            str_replace(
-                '\' . LF . \'',
-                LF,
-                $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['initCommands']
-            ),
-            true
-        );
-        $databaseConnection->setInitializeCommandsAfterConnect($commandsAfterConnect);
-    }
-
-    $GLOBALS['TYPO3_DB'] = $databaseConnection;
-    $GLOBALS['TYPO3_DB']->initialize();
-});