diff --git a/3rdparty b/3rdparty
index 45d8fc9e09fbb..b5c63bed7b21e 160000
--- a/3rdparty
+++ b/3rdparty
@@ -1 +1 @@
-Subproject commit 45d8fc9e09fbb4d3c4de5819afd9a6f72ce00f56
+Subproject commit b5c63bed7b21e25b05de3e0125073d40e4a9e72f
diff --git a/apps/contactsinteraction/lib/Db/CardSearchDao.php b/apps/contactsinteraction/lib/Db/CardSearchDao.php
index 962f9ff768bcf..0929cb7efa098 100644
--- a/apps/contactsinteraction/lib/Db/CardSearchDao.php
+++ b/apps/contactsinteraction/lib/Db/CardSearchDao.php
@@ -29,24 +29,24 @@ public function findExisting(IUser $user,
$cardQuery = $this->db->getQueryBuilder();
$propQuery = $this->db->getQueryBuilder();
- $propOr = $propQuery->expr()->orX();
+ $additionalWheres = [];
if ($uid !== null) {
- $propOr->add($propQuery->expr()->andX(
+ $additionalWheres[] = $propQuery->expr()->andX(
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('UID')),
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($uid))
- ));
+ );
}
if ($email !== null) {
- $propOr->add($propQuery->expr()->andX(
+ $additionalWheres[] = $propQuery->expr()->andX(
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('EMAIL')),
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($email))
- ));
+ );
}
if ($cloudId !== null) {
- $propOr->add($propQuery->expr()->andX(
+ $additionalWheres[] = $propQuery->expr()->andX(
$propQuery->expr()->eq('name', $cardQuery->createNamedParameter('CLOUD')),
$propQuery->expr()->eq('value', $cardQuery->createNamedParameter($cloudId))
- ));
+ );
}
$addressbooksQuery->selectDistinct('id')
->from('addressbooks')
@@ -54,8 +54,12 @@ public function findExisting(IUser $user,
$propQuery->selectDistinct('cardid')
->from('cards_properties')
->where($propQuery->expr()->in('addressbookid', $propQuery->createFunction($addressbooksQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
- ->andWhere($propOr)
->groupBy('cardid');
+
+ if (!empty($additionalWheres)) {
+ $propQuery->andWhere($propQuery->expr()->orX(...$additionalWheres));
+ }
+
$cardQuery->select('carddata')
->from('cards')
->where($cardQuery->expr()->in('id', $cardQuery->createFunction($propQuery->getSQL()), IQueryBuilder::PARAM_INT_ARRAY))
diff --git a/apps/contactsinteraction/lib/Db/RecentContactMapper.php b/apps/contactsinteraction/lib/Db/RecentContactMapper.php
index e0b2ac723fbea..c835b5287c87f 100644
--- a/apps/contactsinteraction/lib/Db/RecentContactMapper.php
+++ b/apps/contactsinteraction/lib/Db/RecentContactMapper.php
@@ -61,23 +61,25 @@ public function findMatch(IUser $user,
?string $cloudId): array {
$qb = $this->db->getQueryBuilder();
- $or = $qb->expr()->orX();
+ $additionalWheres = [];
if ($uid !== null) {
- $or->add($qb->expr()->eq('uid', $qb->createNamedParameter($uid)));
+ $additionalWheres[] = $qb->expr()->eq('uid', $qb->createNamedParameter($uid));
}
if ($email !== null) {
- $or->add($qb->expr()->eq('email', $qb->createNamedParameter($email)));
+ $additionalWheres[] = $qb->expr()->eq('email', $qb->createNamedParameter($email));
}
if ($cloudId !== null) {
- $or->add($qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId)));
+ $additionalWheres[] = $qb->expr()->eq('federated_cloud_id', $qb->createNamedParameter($cloudId));
}
$select = $qb
->select('*')
->from($this->getTableName())
- ->where($or)
- ->andWhere($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID())));
+ ->where($qb->expr()->eq('actor_uid', $qb->createNamedParameter($user->getUID())));
+ if (!empty($additionalWheres)) {
+ $select->andWhere($select->expr()->orX(...$additionalWheres));
+ }
return $this->findEntities($select);
}
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php
index cc6c4344c3c37..df4ed3c0405f5 100644
--- a/apps/dav/lib/CalDAV/CalDavBackend.php
+++ b/apps/dav/lib/CalDAV/CalDavBackend.php
@@ -1874,12 +1874,12 @@ public function search(
}
if (!empty($searchProperties)) {
- $or = $innerQuery->expr()->orX();
+ $or = [];
foreach ($searchProperties as $searchProperty) {
- $or->add($innerQuery->expr()->eq('op.name',
- $outerQuery->createNamedParameter($searchProperty)));
+ $or[] = $innerQuery->expr()->eq('op.name',
+ $outerQuery->createNamedParameter($searchProperty));
}
- $innerQuery->andWhere($or);
+ $innerQuery->andWhere($innerQuery->expr()->orX(...$or));
}
if ($pattern !== '') {
@@ -1923,12 +1923,12 @@ public function search(
}
if (!empty($options['types'])) {
- $or = $outerQuery->expr()->orX();
+ $or = [];
foreach ($options['types'] as $type) {
- $or->add($outerQuery->expr()->eq('componenttype',
- $outerQuery->createNamedParameter($type)));
+ $or[] = $outerQuery->expr()->eq('componenttype',
+ $outerQuery->createNamedParameter($type));
}
- $outerQuery->andWhere($or);
+ $outerQuery->andWhere($outerQuery->expr()->orX(...$or));
}
$outerQuery->andWhere($outerQuery->expr()->in('c.id', $outerQuery->createFunction($innerQuery->getSQL())));
@@ -2149,16 +2149,17 @@ public function searchPrincipalUri(string $principalUri,
$escapePattern = !\array_key_exists('escape_like_param', $options) || $options['escape_like_param'] !== false;
$calendarObjectIdQuery = $this->db->getQueryBuilder();
- $calendarOr = $calendarObjectIdQuery->expr()->orX();
- $searchOr = $calendarObjectIdQuery->expr()->orX();
+ $calendarOr = [];
+ $searchOr = [];
// Fetch calendars and subscription
$calendars = $this->getCalendarsForUser($principalUri);
$subscriptions = $this->getSubscriptionsForUser($principalUri);
foreach ($calendars as $calendar) {
- $calendarAnd = $calendarObjectIdQuery->expr()->andX();
- $calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])));
- $calendarAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)));
+ $calendarAnd = $calendarObjectIdQuery->expr()->andX(
+ $calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$calendar['id'])),
+ $calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_CALENDAR)),
+ );
// If it's shared, limit search to public events
if (isset($calendar['{http://owncloud.org/ns}owner-principal'])
@@ -2166,12 +2167,13 @@ public function searchPrincipalUri(string $principalUri,
$calendarAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
}
- $calendarOr->add($calendarAnd);
+ $calendarOr[] = $calendarAnd;
}
foreach ($subscriptions as $subscription) {
- $subscriptionAnd = $calendarObjectIdQuery->expr()->andX();
- $subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])));
- $subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)));
+ $subscriptionAnd = $calendarObjectIdQuery->expr()->andX(
+ $calendarObjectIdQuery->expr()->eq('cob.calendarid', $calendarObjectIdQuery->createNamedParameter((int)$subscription['id'])),
+ $calendarObjectIdQuery->expr()->eq('cob.calendartype', $calendarObjectIdQuery->createNamedParameter(self::CALENDAR_TYPE_SUBSCRIPTION)),
+ );
// If it's shared, limit search to public events
if (isset($subscription['{http://owncloud.org/ns}owner-principal'])
@@ -2179,28 +2181,30 @@ public function searchPrincipalUri(string $principalUri,
$subscriptionAnd->add($calendarObjectIdQuery->expr()->eq('co.classification', $calendarObjectIdQuery->createNamedParameter(self::CLASSIFICATION_PUBLIC)));
}
- $calendarOr->add($subscriptionAnd);
+ $calendarOr[] = $subscriptionAnd;
}
foreach ($searchProperties as $property) {
- $propertyAnd = $calendarObjectIdQuery->expr()->andX();
- $propertyAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
- $propertyAnd->add($calendarObjectIdQuery->expr()->isNull('cob.parameter'));
+ $propertyAnd = $calendarObjectIdQuery->expr()->andX(
+ $calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)),
+ $calendarObjectIdQuery->expr()->isNull('cob.parameter'),
+ );
- $searchOr->add($propertyAnd);
+ $searchOr[] = $propertyAnd;
}
foreach ($searchParameters as $property => $parameter) {
- $parameterAnd = $calendarObjectIdQuery->expr()->andX();
- $parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)));
- $parameterAnd->add($calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)));
+ $parameterAnd = $calendarObjectIdQuery->expr()->andX(
+ $calendarObjectIdQuery->expr()->eq('cob.name', $calendarObjectIdQuery->createNamedParameter($property, IQueryBuilder::PARAM_STR)),
+ $calendarObjectIdQuery->expr()->eq('cob.parameter', $calendarObjectIdQuery->createNamedParameter($parameter, IQueryBuilder::PARAM_STR_ARRAY)),
+ );
- $searchOr->add($parameterAnd);
+ $searchOr[] = $parameterAnd;
}
- if ($calendarOr->count() === 0) {
+ if (empty($calendarOr)) {
return [];
}
- if ($searchOr->count() === 0) {
+ if (empty($searchOr)) {
return [];
}
@@ -2208,8 +2212,8 @@ public function searchPrincipalUri(string $principalUri,
->from($this->dbObjectPropertiesTable, 'cob')
->leftJoin('cob', 'calendarobjects', 'co', $calendarObjectIdQuery->expr()->eq('co.id', 'cob.objectid'))
->andWhere($calendarObjectIdQuery->expr()->in('co.componenttype', $calendarObjectIdQuery->createNamedParameter($componentTypes, IQueryBuilder::PARAM_STR_ARRAY)))
- ->andWhere($calendarOr)
- ->andWhere($searchOr)
+ ->andWhere($calendarObjectIdQuery->expr()->orX(...$calendarOr))
+ ->andWhere($calendarObjectIdQuery->expr()->orX(...$searchOr))
->andWhere($calendarObjectIdQuery->expr()->isNull('deleted_at'));
if ($pattern !== '') {
diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php
index cdbbc228047f8..9d787c917d34f 100644
--- a/apps/dav/lib/CardDAV/CardDavBackend.php
+++ b/apps/dav/lib/CardDAV/CardDavBackend.php
@@ -1148,20 +1148,20 @@ private function searchByAddressBookIds(array $addressBookIds,
/**
* FIXME Find a way to match only 4 last digits
* BDAY can be --1018 without year or 20001019 with it
- * $bDayOr = $query2->expr()->orX();
+ * $bDayOr = [];
* if ($options['since'] instanceof DateTimeFilter) {
- * $bDayOr->add(
+ * $bDayOr[] =
* $query2->expr()->gte('SUBSTR(cp_bday.value, -4)',
- * $query2->createNamedParameter($options['since']->get()->format('md')))
+ * $query2->createNamedParameter($options['since']->get()->format('md'))
* );
* }
* if ($options['until'] instanceof DateTimeFilter) {
- * $bDayOr->add(
+ * $bDayOr[] =
* $query2->expr()->lte('SUBSTR(cp_bday.value, -4)',
- * $query2->createNamedParameter($options['until']->get()->format('md')))
+ * $query2->createNamedParameter($options['until']->get()->format('md'))
* );
* }
- * $query2->andWhere($bDayOr);
+ * $query2->andWhere($query2->expr()->orX(...$bDayOr));
*/
}
diff --git a/apps/dav/lib/DAV/CustomPropertiesBackend.php b/apps/dav/lib/DAV/CustomPropertiesBackend.php
index ab62ae36c2cc4..f4dd9b2d03857 100644
--- a/apps/dav/lib/DAV/CustomPropertiesBackend.php
+++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php
@@ -411,7 +411,7 @@ private function getUserProperties(string $path, array $requestedProperties) {
// request only a subset
$sql .= ' AND `propertyname` in (?)';
$whereValues[] = $requestedProperties;
- $whereTypes[] = \Doctrine\DBAL\Connection::PARAM_STR_ARRAY;
+ $whereTypes[] = IQueryBuilder::PARAM_STR_ARRAY;
}
$result = $this->connection->executeQuery(
diff --git a/apps/dav/lib/Migration/CalDAVRemoveEmptyValue.php b/apps/dav/lib/Migration/CalDAVRemoveEmptyValue.php
index cbce847a298c2..c7f57dcb11718 100644
--- a/apps/dav/lib/Migration/CalDAVRemoveEmptyValue.php
+++ b/apps/dav/lib/Migration/CalDAVRemoveEmptyValue.php
@@ -5,7 +5,6 @@
*/
namespace OCA\DAV\Migration;
-use Doctrine\DBAL\Platforms\OraclePlatform;
use OCA\DAV\CalDAV\CalDavBackend;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
@@ -75,7 +74,7 @@ public function run(IOutput $output) {
}
protected function getInvalidObjects($pattern) {
- if ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
+ if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
$rows = [];
$chunkSize = 500;
$query = $this->db->getQueryBuilder();
diff --git a/apps/dav/lib/Migration/Version1004Date20170825134824.php b/apps/dav/lib/Migration/Version1004Date20170825134824.php
index 54c4c1947784c..3810c613c8dc3 100644
--- a/apps/dav/lib/Migration/Version1004Date20170825134824.php
+++ b/apps/dav/lib/Migration/Version1004Date20170825134824.php
@@ -233,7 +233,7 @@ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $op
$table->addUniqueIndex(['principaluri', 'uri'], 'calendars_index');
} else {
$table = $schema->getTable('calendars');
- $table->changeColumn('components', [
+ $table->modifyColumn('components', [
'notnull' => false,
'length' => 64,
]);
@@ -323,7 +323,7 @@ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $op
$table->addUniqueIndex(['principaluri', 'uri'], 'calsub_index');
} else {
$table = $schema->getTable('calendarsubscriptions');
- $table->changeColumn('lastmodified', [
+ $table->modifyColumn('lastmodified', [
'notnull' => false,
'unsigned' => true,
]);
diff --git a/apps/federatedfilesharing/lib/Migration/Version1011Date20201120125158.php b/apps/federatedfilesharing/lib/Migration/Version1011Date20201120125158.php
index 78517e3a29731..8e9c6dbb2bf28 100644
--- a/apps/federatedfilesharing/lib/Migration/Version1011Date20201120125158.php
+++ b/apps/federatedfilesharing/lib/Migration/Version1011Date20201120125158.php
@@ -32,7 +32,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
if ($schema->hasTable('federated_reshares')) {
$table = $schema->getTable('federated_reshares');
$remoteIdColumn = $table->getColumn('remote_id');
- if ($remoteIdColumn && $remoteIdColumn->getType()->getName() !== Types::STRING) {
+ if (Types::getType($remoteIdColumn->getType()) !== Types::STRING) {
$remoteIdColumn->setNotnull(false);
$remoteIdColumn->setType(Type::getType(Types::STRING));
$remoteIdColumn->setOptions(['length' => 255]);
diff --git a/apps/files_external/lib/Migration/Version1011Date20200630192246.php b/apps/files_external/lib/Migration/Version1011Date20200630192246.php
index c87b1cfbc8be9..dffbd70aa5868 100644
--- a/apps/files_external/lib/Migration/Version1011Date20200630192246.php
+++ b/apps/files_external/lib/Migration/Version1011Date20200630192246.php
@@ -103,7 +103,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table->addUniqueIndex(['mount_id', 'key'], 'config_mount_key');
} else {
$table = $schema->getTable('external_config');
- $table->changeColumn('value', [
+ $table->modifyColumn('value', [
'notnull' => false,
'length' => 4000,
]);
diff --git a/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php b/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php
index 21dbb64fef066..6c7f323a8f75a 100644
--- a/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php
+++ b/apps/files_sharing/lib/Migration/Version11300Date20201120141438.php
@@ -90,7 +90,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
} else {
$table = $schema->getTable('share_external');
$remoteIdColumn = $table->getColumn('remote_id');
- if ($remoteIdColumn && $remoteIdColumn->getType()->getName() !== Types::STRING) {
+ if (Types::getType($remoteIdColumn->getType()) !== Types::STRING) {
$remoteIdColumn->setNotnull(false);
$remoteIdColumn->setType(Type::getType(Types::STRING));
$remoteIdColumn->setOptions(['length' => 255]);
diff --git a/apps/settings/lib/SetupChecks/SupportedDatabase.php b/apps/settings/lib/SetupChecks/SupportedDatabase.php
index 89f789483059b..fa42516a87a8a 100644
--- a/apps/settings/lib/SetupChecks/SupportedDatabase.php
+++ b/apps/settings/lib/SetupChecks/SupportedDatabase.php
@@ -11,7 +11,7 @@
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
+use Doctrine\DBAL\Platforms\SQLitePlatform;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IURLGenerator;
@@ -103,7 +103,7 @@ public function run(): SetupResult {
}
} elseif ($databasePlatform instanceof OraclePlatform) {
$version = 'Oracle';
- } elseif ($databasePlatform instanceof SqlitePlatform) {
+ } elseif ($databasePlatform instanceof SQLitePlatform) {
return SetupResult::warning(
$this->l10n->t('SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend. This is particularly recommended when using the desktop client for file synchronisation. To migrate to another database use the command line tool: "occ db:convert-type".'),
$this->urlGenerator->linkToDocs('admin-db-conversion')
diff --git a/apps/settings/tests/SetupChecks/SupportedDatabaseTest.php b/apps/settings/tests/SetupChecks/SupportedDatabaseTest.php
index 2492379b557ca..0ba1621c5febb 100644
--- a/apps/settings/tests/SetupChecks/SupportedDatabaseTest.php
+++ b/apps/settings/tests/SetupChecks/SupportedDatabaseTest.php
@@ -8,7 +8,6 @@
*/
namespace OCA\Settings\Tests;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use OCA\Settings\SetupChecks\SupportedDatabase;
use OCP\IDBConnection;
use OCP\IL10N;
@@ -41,8 +40,7 @@ protected function setUp(): void {
}
public function testPass(): void {
- $platform = $this->connection->getDatabasePlatform();
- if ($platform instanceof SqlitePlatform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
/** SQlite always gets a warning */
$this->assertEquals(SetupResult::WARNING, $this->check->run()->getSeverity());
} else {
diff --git a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php
index 2ca390e6eddb6..8c0fb692bbf5c 100644
--- a/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php
+++ b/apps/twofactor_backupcodes/lib/Migration/Version1002Date20170919123342.php
@@ -9,8 +9,8 @@
namespace OCA\TwoFactorBackupCodes\Migration;
use Doctrine\DBAL\Types\Type;
-use Doctrine\DBAL\Types\Types;
use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
@@ -32,7 +32,7 @@ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $op
$column->setDefault('');
$column = $table->getColumn('used');
- if ($column->getType()->getName() !== Types::SMALLINT) {
+ if (Types::getType($column->getType()) !== Types::SMALLINT) {
$column->setType(Type::getType(Types::SMALLINT));
$column->setOptions(['length' => 6]);
}
diff --git a/apps/user_ldap/lib/Mapping/AbstractMapping.php b/apps/user_ldap/lib/Mapping/AbstractMapping.php
index c243731eaf7a3..9b92960d3546c 100644
--- a/apps/user_ldap/lib/Mapping/AbstractMapping.php
+++ b/apps/user_ldap/lib/Mapping/AbstractMapping.php
@@ -8,9 +8,9 @@
namespace OCA\User_LDAP\Mapping;
use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use OCP\DB\IPreparedStatement;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
use Psr\Log\LoggerInterface;
/**
@@ -202,7 +202,7 @@ protected function prepareListOfIdsQuery(array $hashList): IQueryBuilder {
protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$results): void {
$stmt = $qb->executeQuery();
- while ($entry = $stmt->fetch(\Doctrine\DBAL\FetchMode::ASSOCIATIVE)) {
+ while ($entry = $stmt->fetch()) {
$results[$entry['ldap_dn']] = $entry['owncloud_name'];
$this->cache[$entry['ldap_dn']] = $entry['owncloud_name'];
}
@@ -216,7 +216,7 @@ protected function collectResultsFromListOfIdsQuery(IQueryBuilder $qb, array &$r
public function getListOfIdsByDn(array $fdns): array {
$totalDBParamLimit = 65000;
$sliceSize = 1000;
- $maxSlices = $this->dbc->getDatabasePlatform() instanceof SqlitePlatform ? 9 : $totalDBParamLimit / $sliceSize;
+ $maxSlices = $this->dbc->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE ? 9 : $totalDBParamLimit / $sliceSize;
$results = [];
$slice = 1;
diff --git a/apps/workflowengine/lib/Migration/Version2200Date20210805101925.php b/apps/workflowengine/lib/Migration/Version2200Date20210805101925.php
index 841277acfcebc..f924b7ae8ef02 100644
--- a/apps/workflowengine/lib/Migration/Version2200Date20210805101925.php
+++ b/apps/workflowengine/lib/Migration/Version2200Date20210805101925.php
@@ -27,7 +27,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
if ($schema->hasTable('flow_operations')) {
$table = $schema->getTable('flow_operations');
- $table->changeColumn('name', [
+ $table->modifyColumn('name', [
'notnull' => false,
]);
}
diff --git a/core/Command/Db/AddMissingPrimaryKeys.php b/core/Command/Db/AddMissingPrimaryKeys.php
index 073ce7538ccc0..539720cc639f0 100644
--- a/core/Command/Db/AddMissingPrimaryKeys.php
+++ b/core/Command/Db/AddMissingPrimaryKeys.php
@@ -55,7 +55,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
foreach ($missingKeys as $missingKey) {
if ($schema->hasTable($missingKey['tableName'])) {
$table = $schema->getTable($missingKey['tableName']);
- if (!$table->hasPrimaryKey()) {
+ if (!$table->getPrimaryKey()) {
$output->writeln('Adding primary key to the ' . $missingKey['tableName'] . ' table, this can take some time...');
$table->setPrimaryKey($missingKey['columns'], $missingKey['primaryKeyName']);
diff --git a/core/Command/Db/ConvertFilecacheBigInt.php b/core/Command/Db/ConvertFilecacheBigInt.php
index 5f3e790e9ceb8..0375823c36c16 100644
--- a/core/Command/Db/ConvertFilecacheBigInt.php
+++ b/core/Command/Db/ConvertFilecacheBigInt.php
@@ -5,11 +5,11 @@
*/
namespace OC\Core\Command\Db;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Types\Type;
use OC\DB\Connection;
use OC\DB\SchemaWrapper;
use OCP\DB\Types;
+use OCP\IDBConnection;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -53,7 +53,7 @@ public static function getColumnsByTable(): array {
protected function execute(InputInterface $input, OutputInterface $output): int {
$schema = new SchemaWrapper($this->connection);
- $isSqlite = $this->connection->getDatabasePlatform() instanceof SqlitePlatform;
+ $isSqlite = $this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE;
$updates = [];
$tables = static::getColumnsByTable();
@@ -68,7 +68,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$column = $table->getColumn($columnName);
$isAutoIncrement = $column->getAutoincrement();
$isAutoIncrementOnSqlite = $isSqlite && $isAutoIncrement;
- if ($column->getType()->getName() !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
+ if (Types::getType($column->getType()) !== Types::BIGINT && !$isAutoIncrementOnSqlite) {
$column->setType(Type::getType(Types::BIGINT));
$column->setOptions(['length' => 20]);
diff --git a/core/Command/Db/ConvertMysqlToMB4.php b/core/Command/Db/ConvertMysqlToMB4.php
index 679cdd5f61611..618e15de3f45a 100644
--- a/core/Command/Db/ConvertMysqlToMB4.php
+++ b/core/Command/Db/ConvertMysqlToMB4.php
@@ -5,7 +5,6 @@
*/
namespace OC\Core\Command\Db;
-use Doctrine\DBAL\Platforms\MySQLPlatform;
use OC\DB\MySqlTools;
use OC\Migration\ConsoleOutput;
use OC\Repair\Collation;
@@ -34,7 +33,7 @@ protected function configure() {
}
protected function execute(InputInterface $input, OutputInterface $output): int {
- if (!$this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
+ if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_MYSQL) {
$output->writeln("This command is only valid for MySQL/MariaDB databases.");
return 1;
}
diff --git a/core/Command/Db/ConvertType.php b/core/Command/Db/ConvertType.php
index 333f29625f62f..2d4cf4f9af620 100644
--- a/core/Command/Db/ConvertType.php
+++ b/core/Command/Db/ConvertType.php
@@ -9,6 +9,7 @@
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\AbstractAsset;
+use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table;
use OC\DB\Connection;
use OC\DB\ConnectionFactory;
@@ -245,7 +246,7 @@ protected function clearSchema(Connection $db, InputInterface $input, OutputInte
$output->writeln('Clearing schema in new database');
}
foreach ($toTables as $table) {
- $db->getSchemaManager()->dropTable($table);
+ $db->createSchemaManager()->dropTable($table);
}
}
@@ -258,7 +259,7 @@ protected function getTables(Connection $db) {
}
return preg_match($filterExpression, $asset) !== false;
});
- return $db->getSchemaManager()->listTableNames();
+ return $db->createSchemaManager()->listTableNames();
}
/**
@@ -302,7 +303,12 @@ protected function copyTable(Connection $fromDB, Connection $toDB, Table $table,
->setMaxResults($chunkSize);
try {
- $orderColumns = $table->getPrimaryKeyColumns();
+ $key = $table->getPrimaryKey();
+ if ($key instanceof Index) {
+ $orderColumns = $key->getColumns();
+ } else {
+ $orderColumns = $table->getColumns();
+ }
} catch (Exception $e) {
$orderColumns = $table->getColumns();
}
@@ -362,7 +368,7 @@ protected function getColumnType(Table $table, $columnName) {
return $this->columnTypes[$tableName][$columnName];
}
- $type = $table->getColumn($columnName)->getType()->getName();
+ $type = Types::getType($table->getColumn($columnName)->getType());
switch ($type) {
case Types::BLOB:
diff --git a/core/Migrations/Version13000Date20170718121200.php b/core/Migrations/Version13000Date20170718121200.php
index c485e025c3709..3985bdaeb57e6 100644
--- a/core/Migrations/Version13000Date20170718121200.php
+++ b/core/Migrations/Version13000Date20170718121200.php
@@ -5,7 +5,6 @@
*/
namespace OC\Core\Migrations;
-use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\IDBConnection;
@@ -238,7 +237,7 @@ public function changeSchema(IOutput $output, \Closure $schemaClosure, array $op
$table->addIndex(['name'], 'fs_name_hash');
$table->addIndex(['mtime'], 'fs_mtime');
$table->addIndex(['size'], 'fs_size');
- if (!$schema->getDatabasePlatform() instanceof PostgreSQL94Platform) {
+ if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_POSTGRES) {
$table->addIndex(['storage', 'path'], 'fs_storage_path_prefix', [], ['lengths' => [null, 64]]);
}
}
diff --git a/core/Migrations/Version21000Date20201120141228.php b/core/Migrations/Version21000Date20201120141228.php
index ac20cbfd577af..feba7c469bb4a 100644
--- a/core/Migrations/Version21000Date20201120141228.php
+++ b/core/Migrations/Version21000Date20201120141228.php
@@ -24,16 +24,16 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
if ($loginNameColumn->getLength() !== 255) {
$loginNameColumn->setLength(255);
}
- $table->changeColumn('type', [
+ $table->modifyColumn('type', [
'notnull' => false,
]);
- $table->changeColumn('remember', [
+ $table->modifyColumn('remember', [
'notnull' => false,
]);
- $table->changeColumn('last_activity', [
+ $table->modifyColumn('last_activity', [
'notnull' => false,
]);
- $table->changeColumn('last_check', [
+ $table->modifyColumn('last_check', [
'notnull' => false,
]);
}
@@ -51,7 +51,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
if ($schema->hasTable('jobs')) {
$table = $schema->getTable('jobs');
- $table->changeColumn('execution_duration', [
+ $table->modifyColumn('execution_duration', [
'notnull' => false,
'default' => 0,
]);
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 958223bf2fc0f..93357dbc8e3da 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1321,12 +1321,18 @@
'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php',
'OC\\DB\\AdapterPgSql' => $baseDir . '/lib/private/DB/AdapterPgSql.php',
'OC\\DB\\AdapterSqlite' => $baseDir . '/lib/private/DB/AdapterSqlite.php',
- 'OC\\DB\\BacktraceDebugStack' => $baseDir . '/lib/private/DB/BacktraceDebugStack.php',
'OC\\DB\\Connection' => $baseDir . '/lib/private/DB/Connection.php',
'OC\\DB\\ConnectionAdapter' => $baseDir . '/lib/private/DB/ConnectionAdapter.php',
'OC\\DB\\ConnectionFactory' => $baseDir . '/lib/private/DB/ConnectionFactory.php',
'OC\\DB\\DbDataCollector' => $baseDir . '/lib/private/DB/DbDataCollector.php',
'OC\\DB\\Exceptions\\DbalException' => $baseDir . '/lib/private/DB/Exceptions/DbalException.php',
+ 'OC\\DB\\Logging\\Connection' => $baseDir . '/lib/private/DB/Logging/Connection.php',
+ 'OC\\DB\\Logging\\Driver' => $baseDir . '/lib/private/DB/Logging/Driver.php',
+ 'OC\\DB\\Logging\\Middleware' => $baseDir . '/lib/private/DB/Logging/Middleware.php',
+ 'OC\\DB\\Logging\\Statement' => $baseDir . '/lib/private/DB/Logging/Statement.php',
+ 'OC\\DB\\Middlewares\\SQLiteCaseSensitiveLike' => $baseDir . '/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php',
+ 'OC\\DB\\Middlewares\\SQLiteJournalMode' => $baseDir . '/lib/private/DB/Middlewares/SQLiteJournalMode.php',
+ 'OC\\DB\\Middlewares\\SetTransactionIsolationLevel' => $baseDir . '/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php',
'OC\\DB\\MigrationException' => $baseDir . '/lib/private/DB/MigrationException.php',
'OC\\DB\\MigrationService' => $baseDir . '/lib/private/DB/MigrationService.php',
'OC\\DB\\Migrator' => $baseDir . '/lib/private/DB/Migrator.php',
@@ -1335,7 +1341,6 @@
'OC\\DB\\MissingIndexInformation' => $baseDir . '/lib/private/DB/MissingIndexInformation.php',
'OC\\DB\\MissingPrimaryKeyInformation' => $baseDir . '/lib/private/DB/MissingPrimaryKeyInformation.php',
'OC\\DB\\MySqlTools' => $baseDir . '/lib/private/DB/MySqlTools.php',
- 'OC\\DB\\OCSqlitePlatform' => $baseDir . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\ObjectParameter' => $baseDir . '/lib/private/DB/ObjectParameter.php',
'OC\\DB\\OracleConnection' => $baseDir . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php',
@@ -1358,9 +1363,8 @@
'OC\\DB\\QueryBuilder\\QuoteHelper' => $baseDir . '/lib/private/DB/QueryBuilder/QuoteHelper.php',
'OC\\DB\\ResultAdapter' => $baseDir . '/lib/private/DB/ResultAdapter.php',
'OC\\DB\\SQLiteMigrator' => $baseDir . '/lib/private/DB/SQLiteMigrator.php',
- 'OC\\DB\\SQLiteSessionInit' => $baseDir . '/lib/private/DB/SQLiteSessionInit.php',
'OC\\DB\\SchemaWrapper' => $baseDir . '/lib/private/DB/SchemaWrapper.php',
- 'OC\\DB\\SetTransactionIsolationLevel' => $baseDir . '/lib/private/DB/SetTransactionIsolationLevel.php',
+ 'OC\\DB\\TDoctrineParameterTypeMap' => $baseDir . '/lib/private/DB/TDoctrineParameterTypeMap.php',
'OC\\Dashboard\\Manager' => $baseDir . '/lib/private/Dashboard/Manager.php',
'OC\\DatabaseException' => $baseDir . '/lib/private/DatabaseException.php',
'OC\\DatabaseSetupException' => $baseDir . '/lib/private/DatabaseSetupException.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index df24fac37657e..7461a567cfb9b 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1354,12 +1354,18 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php',
'OC\\DB\\AdapterPgSql' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterPgSql.php',
'OC\\DB\\AdapterSqlite' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterSqlite.php',
- 'OC\\DB\\BacktraceDebugStack' => __DIR__ . '/../../..' . '/lib/private/DB/BacktraceDebugStack.php',
'OC\\DB\\Connection' => __DIR__ . '/../../..' . '/lib/private/DB/Connection.php',
'OC\\DB\\ConnectionAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionAdapter.php',
'OC\\DB\\ConnectionFactory' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionFactory.php',
'OC\\DB\\DbDataCollector' => __DIR__ . '/../../..' . '/lib/private/DB/DbDataCollector.php',
'OC\\DB\\Exceptions\\DbalException' => __DIR__ . '/../../..' . '/lib/private/DB/Exceptions/DbalException.php',
+ 'OC\\DB\\Logging\\Connection' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Connection.php',
+ 'OC\\DB\\Logging\\Driver' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Driver.php',
+ 'OC\\DB\\Logging\\Middleware' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Middleware.php',
+ 'OC\\DB\\Logging\\Statement' => __DIR__ . '/../../..' . '/lib/private/DB/Logging/Statement.php',
+ 'OC\\DB\\Middlewares\\SQLiteCaseSensitiveLike' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php',
+ 'OC\\DB\\Middlewares\\SQLiteJournalMode' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SQLiteJournalMode.php',
+ 'OC\\DB\\Middlewares\\SetTransactionIsolationLevel' => __DIR__ . '/../../..' . '/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php',
'OC\\DB\\MigrationException' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationException.php',
'OC\\DB\\MigrationService' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationService.php',
'OC\\DB\\Migrator' => __DIR__ . '/../../..' . '/lib/private/DB/Migrator.php',
@@ -1368,7 +1374,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DB\\MissingIndexInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingIndexInformation.php',
'OC\\DB\\MissingPrimaryKeyInformation' => __DIR__ . '/../../..' . '/lib/private/DB/MissingPrimaryKeyInformation.php',
'OC\\DB\\MySqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/MySqlTools.php',
- 'OC\\DB\\OCSqlitePlatform' => __DIR__ . '/../../..' . '/lib/private/DB/OCSqlitePlatform.php',
'OC\\DB\\ObjectParameter' => __DIR__ . '/../../..' . '/lib/private/DB/ObjectParameter.php',
'OC\\DB\\OracleConnection' => __DIR__ . '/../../..' . '/lib/private/DB/OracleConnection.php',
'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php',
@@ -1391,9 +1396,8 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\DB\\QueryBuilder\\QuoteHelper' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/QuoteHelper.php',
'OC\\DB\\ResultAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ResultAdapter.php',
'OC\\DB\\SQLiteMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteMigrator.php',
- 'OC\\DB\\SQLiteSessionInit' => __DIR__ . '/../../..' . '/lib/private/DB/SQLiteSessionInit.php',
'OC\\DB\\SchemaWrapper' => __DIR__ . '/../../..' . '/lib/private/DB/SchemaWrapper.php',
- 'OC\\DB\\SetTransactionIsolationLevel' => __DIR__ . '/../../..' . '/lib/private/DB/SetTransactionIsolationLevel.php',
+ 'OC\\DB\\TDoctrineParameterTypeMap' => __DIR__ . '/../../..' . '/lib/private/DB/TDoctrineParameterTypeMap.php',
'OC\\Dashboard\\Manager' => __DIR__ . '/../../..' . '/lib/private/Dashboard/Manager.php',
'OC\\DatabaseException' => __DIR__ . '/../../..' . '/lib/private/DatabaseException.php',
'OC\\DatabaseSetupException' => __DIR__ . '/../../..' . '/lib/private/DatabaseSetupException.php',
diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php
index d05fe440202dd..58eee772fbf91 100644
--- a/lib/private/AllConfig.php
+++ b/lib/private/AllConfig.php
@@ -6,7 +6,6 @@
*/
namespace OC;
-use Doctrine\DBAL\Platforms\OraclePlatform;
use OCP\Cache\CappedMemoryCache;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
@@ -470,7 +469,7 @@ public function getUsersForUserValue($appName, $key, $value) {
$this->fixDIInit();
$qb = $this->connection->getQueryBuilder();
- $configValueColumn = ($this->connection->getDatabasePlatform() instanceof OraclePlatform)
+ $configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE)
? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR)
: 'configvalue';
$result = $qb->select('userid')
@@ -509,7 +508,7 @@ public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
}
$qb = $this->connection->getQueryBuilder();
- $configValueColumn = ($this->connection->getDatabasePlatform() instanceof OraclePlatform)
+ $configValueColumn = ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE)
? $qb->expr()->castColumn('configvalue', IQueryBuilder::PARAM_STR)
: 'configvalue';
diff --git a/lib/private/BackgroundJob/JobList.php b/lib/private/BackgroundJob/JobList.php
index 61c48b0eab218..cefd1e6a8927d 100644
--- a/lib/private/BackgroundJob/JobList.php
+++ b/lib/private/BackgroundJob/JobList.php
@@ -7,7 +7,6 @@
*/
namespace OC\BackgroundJob;
-use Doctrine\DBAL\Platforms\MySQLPlatform;
use OCP\AppFramework\QueryException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\AutoloadNotAllowedException;
@@ -98,7 +97,7 @@ public function remove($job, $argument = null): void {
// Add galera safe delete chunking if using mysql
// Stops us hitting wsrep_max_ws_rows when large row counts are deleted
- if ($this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL) {
// Then use chunked delete
$max = IQueryBuilder::MAX_ROW_DELETION;
@@ -204,12 +203,12 @@ public function getNext(bool $onlyTimeSensitive = false, ?array $jobClasses = nu
$query->andWhere($query->expr()->eq('time_sensitive', $query->createNamedParameter(IJob::TIME_SENSITIVE, IQueryBuilder::PARAM_INT)));
}
- if ($jobClasses !== null && count($jobClasses) > 0) {
- $orClasses = $query->expr()->orx();
+ if (!empty($jobClasses)) {
+ $orClasses = [];
foreach ($jobClasses as $jobClass) {
- $orClasses->add($query->expr()->eq('class', $query->createNamedParameter($jobClass, IQueryBuilder::PARAM_STR)));
+ $orClasses[] = $query->expr()->eq('class', $query->createNamedParameter($jobClass, IQueryBuilder::PARAM_STR));
}
- $query->andWhere($orClasses);
+ $query->andWhere($query->expr()->orX(...$orClasses));
}
$result = $query->executeQuery();
diff --git a/lib/private/DB/BacktraceDebugStack.php b/lib/private/DB/BacktraceDebugStack.php
deleted file mode 100644
index 4afd3ce6a1342..0000000000000
--- a/lib/private/DB/BacktraceDebugStack.php
+++ /dev/null
@@ -1,20 +0,0 @@
-queries[$this->currentQuery]['backtrace'] = $backtrace;
- $this->queries[$this->currentQuery]['start'] = $this->start;
- }
-}
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index c886cb202353f..271560a1f1452 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -8,16 +8,18 @@
*/
namespace OC\DB;
-use Doctrine\Common\EventManager;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\Configuration;
+use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\ConnectionLost;
+use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
+use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
+use Doctrine\DBAL\Platforms\SQLitePlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Statement;
@@ -25,6 +27,8 @@
use OC\SystemConfig;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Diagnostics\IEventLogger;
+use OCP\Diagnostics\IQueryLogger;
+use OCP\IDBConnection;
use OCP\IRequestId;
use OCP\PreConditionNotMetException;
use OCP\Profiler\IProfiler;
@@ -36,6 +40,8 @@
use function in_array;
class Connection extends PrimaryReadReplicaConnection {
+ use TDoctrineParameterTypeMap;
+
/** @var string */
protected $tablePrefix;
@@ -78,7 +84,6 @@ public function __construct(
private array $params,
Driver $driver,
?Configuration $config = null,
- ?EventManager $eventManager = null
) {
if (!isset($params['adapter'])) {
throw new \Exception('adapter not set');
@@ -89,7 +94,7 @@ public function __construct(
/**
* @psalm-suppress InternalMethod
*/
- parent::__construct($params, $driver, $config, $eventManager);
+ parent::__construct($params, $driver, $config);
$this->adapter = new $params['adapter']($this);
$this->tablePrefix = $params['tablePrefix'];
@@ -100,14 +105,11 @@ public function __construct(
$this->logRequestId = $this->systemConfig->getValue('db.log_request_id', false);
$this->requestId = Server::get(IRequestId::class)->getId();
- /** @var \OCP\Profiler\IProfiler */
+ /** @var IProfiler */
$profiler = Server::get(IProfiler::class);
if ($profiler->isEnabled()) {
- $this->dbDataCollector = new DbDataCollector($this);
+ $this->dbDataCollector = new DbDataCollector(Server::get(IQueryLogger::class));
$profiler->add($this->dbDataCollector);
- $debugStack = new BacktraceDebugStack();
- $this->dbDataCollector->setDebugStack($debugStack);
- $this->_config->setSQLLogger($debugStack);
}
$this->setNestTransactionsWithSavepoints(true);
@@ -116,7 +118,7 @@ public function __construct(
/**
* @throws Exception
*/
- public function connect($connectionName = null) {
+ public function connect(?string $connectionName = null): Driver\Connection {
try {
if ($this->_conn) {
$this->reconnectIfNeeded();
@@ -136,11 +138,11 @@ public function connect($connectionName = null) {
return $status;
} catch (Exception $e) {
// throw a new exception to prevent leaking info from the stacktrace
- throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
+ throw new ConnectionException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
}
}
- protected function performConnect(?string $connectionName = null): bool {
+ protected function performConnect(?string $connectionName = null): Driver\Connection {
if (($connectionName ?? 'replica') === 'replica'
&& count($this->params['replica']) === 1
&& $this->params['primary'] === $this->params['replica'][0]) {
@@ -174,26 +176,13 @@ public function getQueryBuilder(): IQueryBuilder {
* @return \Doctrine\DBAL\Query\QueryBuilder
* @deprecated please use $this->getQueryBuilder() instead
*/
- public function createQueryBuilder() {
+ public function createQueryBuilder(): \Doctrine\DBAL\Query\QueryBuilder {
$backtrace = $this->getCallerBacktrace();
$this->logger->debug('Doctrine QueryBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
$this->queriesBuilt++;
return parent::createQueryBuilder();
}
- /**
- * Gets the ExpressionBuilder for the connection.
- *
- * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
- * @deprecated please use $this->getQueryBuilder()->expr() instead
- */
- public function getExpressionBuilder() {
- $backtrace = $this->getCallerBacktrace();
- $this->logger->debug('Doctrine ExpressionBuilder retrieved in {backtrace}', ['app' => 'core', 'backtrace' => $backtrace]);
- $this->queriesBuilt++;
- return parent::getExpressionBuilder();
- }
-
/**
* Get the file and line that called the method where `getCallerBacktrace()` was used
*
@@ -301,6 +290,7 @@ public function executeQuery(string $sql, array $params = [], $types = [], ?Quer
$sql = $this->finishQuery($sql);
$this->queriesExecuted++;
$this->logQueryToFile($sql);
+ $types = array_map($this->convertParameterTypeToDoctrine(...), $types);
return parent::executeQuery($sql, $params, $types, $qcp);
}
@@ -318,10 +308,7 @@ private function getQueriedTables(string $sql): array {
* @throws Exception
*/
public function executeUpdate(string $sql, array $params = [], array $types = []): int {
- $sql = $this->finishQuery($sql);
- $this->queriesExecuted++;
- $this->logQueryToFile($sql);
- return parent::executeUpdate($sql, $params, $types);
+ return $this->executeStatement($sql, $params, $types);
}
/**
@@ -334,7 +321,7 @@ public function executeUpdate(string $sql, array $params = [], array $types = []
* @param array $params The query parameters.
* @param array $types The parameter types.
*
- * @return int The number of affected rows.
+ * @return int The number of affected rows, if the result is bigger than PHP_INT_MAX, PHP_INT_MAX is returned
*
* @throws \Doctrine\DBAL\Exception
*/
@@ -472,22 +459,22 @@ public function setValues(string $table, array $keys, array $values, array $upda
foreach ($values as $name => $value) {
$updateQb->set($name, $updateQb->createNamedParameter($value, $this->getType($value)));
}
- $where = $updateQb->expr()->andX();
+ $where = [];
$whereValues = array_merge($keys, $updatePreconditionValues);
foreach ($whereValues as $name => $value) {
if ($value === '') {
- $where->add($updateQb->expr()->emptyString(
+ $where[] = $updateQb->expr()->emptyString(
$name
- ));
+ );
} else {
- $where->add($updateQb->expr()->eq(
+ $where[] = $updateQb->expr()->eq(
$name,
$updateQb->createNamedParameter($value, $this->getType($value)),
$this->getType($value)
- ));
+ );
}
}
- $updateQb->where($where);
+ $updateQb->where($updateQb->expr()->andX(...$where));
$affected = $updateQb->executeStatement();
if ($affected === 0 && !empty($updatePreconditionValues)) {
@@ -561,7 +548,7 @@ public function errorInfo() {
*/
public function dropTable($table) {
$table = $this->tablePrefix . trim($table);
- $schema = $this->getSchemaManager();
+ $schema = $this->createSchemaManager();
if ($schema->tablesExist([$table])) {
$schema->dropTable($table);
}
@@ -577,7 +564,7 @@ public function dropTable($table) {
*/
public function tableExists($table) {
$table = $this->tablePrefix . trim($table);
- $schema = $this->getSchemaManager();
+ $schema = $this->createSchemaManager();
return $schema->tablesExist([$table]);
}
@@ -671,7 +658,7 @@ private function getMigrator() {
$platform = $this->getDatabasePlatform();
$config = \OC::$server->getConfig();
$dispatcher = Server::get(\OCP\EventDispatcher\IEventDispatcher::class);
- if ($platform instanceof SqlitePlatform) {
+ if ($platform instanceof SQLitePlatform) {
return new SQLiteMigrator($this, $config, $dispatcher);
} elseif ($platform instanceof OraclePlatform) {
return new OracleMigrator($this, $config, $dispatcher);
@@ -680,15 +667,15 @@ private function getMigrator() {
}
}
- public function beginTransaction() {
+ public function beginTransaction(): void {
if (!$this->inTransaction()) {
$this->transactionActiveSince = microtime(true);
}
- return parent::beginTransaction();
+ parent::beginTransaction();
}
- public function commit() {
- $result = parent::commit();
+ public function commit(): void {
+ parent::commit();
if ($this->getTransactionNestingLevel() === 0) {
$timeTook = microtime(true) - $this->transactionActiveSince;
$this->transactionActiveSince = null;
@@ -696,11 +683,10 @@ public function commit() {
$this->logger->debug('Transaction took ' . $timeTook . 's', ['exception' => new \Exception('Transaction took ' . $timeTook . 's')]);
}
}
- return $result;
}
- public function rollBack() {
- $result = parent::rollBack();
+ public function rollBack(): void {
+ parent::rollBack();
if ($this->getTransactionNestingLevel() === 0) {
$timeTook = microtime(true) - $this->transactionActiveSince;
$this->transactionActiveSince = null;
@@ -708,7 +694,6 @@ public function rollBack() {
$this->logger->debug('Transaction rollback took longer than 1s: ' . $timeTook, ['exception' => new \Exception('Long running transaction rollback')]);
}
}
- return $result;
}
private function reconnectIfNeeded(): void {
@@ -721,7 +706,7 @@ private function reconnectIfNeeded(): void {
}
try {
- $this->_conn->query($this->getDriver()->getDatabasePlatform()->getDummySelectSQL());
+ $this->_conn->query($this->getDatabasePlatform()->getDummySelectSQL());
$this->lastConnectionCheck[$this->getConnectionName()] = time();
} catch (ConnectionLost|\Exception $e) {
$this->logger->warning('Exception during connectivity check, closing and reconnecting', ['exception' => $e]);
@@ -732,4 +717,19 @@ private function reconnectIfNeeded(): void {
private function getConnectionName(): string {
return $this->isConnectedToPrimary() ? 'primary' : 'replica';
}
+
+ public function getDatabaseProvider(): string {
+ $platform = $this->getDatabasePlatform();
+ if ($platform instanceof MySQLPlatform) {
+ return IDBConnection::PLATFORM_MYSQL;
+ } elseif ($platform instanceof OraclePlatform) {
+ return IDBConnection::PLATFORM_ORACLE;
+ } elseif ($platform instanceof PostgreSQLPlatform) {
+ return IDBConnection::PLATFORM_POSTGRES;
+ } elseif ($platform instanceof SQLitePlatform) {
+ return IDBConnection::PLATFORM_SQLITE;
+ } else {
+ throw new \Exception('Database ' . $platform::class . ' not supported');
+ }
+ }
}
diff --git a/lib/private/DB/ConnectionAdapter.php b/lib/private/DB/ConnectionAdapter.php
index 86a901a7de33d..52e2ab3261e19 100644
--- a/lib/private/DB/ConnectionAdapter.php
+++ b/lib/private/DB/ConnectionAdapter.php
@@ -13,7 +13,7 @@
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
+use Doctrine\DBAL\Platforms\SQLitePlatform;
use Doctrine\DBAL\Schema\Schema;
use OC\DB\Exceptions\DbalException;
use OCP\DB\IPreparedStatement;
@@ -25,11 +25,9 @@
* Adapts the public API to our internal DBAL connection wrapper
*/
class ConnectionAdapter implements IDBConnection {
- /** @var Connection */
- private $inner;
-
- public function __construct(Connection $inner) {
- $this->inner = $inner;
+ public function __construct(
+ protected Connection $inner,
+ ) {
}
public function getQueryBuilder(): IQueryBuilder {
@@ -162,7 +160,8 @@ public function errorInfo() {
public function connect(): bool {
try {
- return $this->inner->connect();
+ $this->inner->connect();
+ return true;
} catch (Exception $e) {
throw DbalException::wrap($e);
}
@@ -172,12 +171,21 @@ public function close(): void {
$this->inner->close();
}
+ /**
+ * @param mixed $input
+ * @param int $type
+ * @deprecated 30.0.0 Only strings are supported as database type in the end and the $type parameter is ignored going forward
+ */
public function quote($input, $type = IQueryBuilder::PARAM_STR) {
- return $this->inner->quote($input, $type);
+ if ($type !== IQueryBuilder::PARAM_STR) {
+ \OC::$server->getLogger()->debug('Parameter $type is no longer supported and the function only handles resulting database type string', ['exception' => new \InvalidArgumentException('$type parameter is no longer supported')]);
+ }
+ return $this->inner->getDatabasePlatform()->quoteStringLiteral($input);
}
/**
* @todo we are leaking a 3rdparty type here
+ * @deprecated 30.0.0 Use {@see getDatabaseProvider()} instead
*/
public function getDatabasePlatform(): AbstractPlatform {
return $this->inner->getDatabasePlatform();
@@ -230,18 +238,10 @@ public function getInner(): Connection {
return $this->inner;
}
+ /**
+ * @return self::PLATFORM_MYSQL|self::PLATFORM_ORACLE|self::PLATFORM_POSTGRES|self::PLATFORM_SQLITE
+ */
public function getDatabaseProvider(): string {
- $platform = $this->inner->getDatabasePlatform();
- if ($platform instanceof MySQLPlatform) {
- return IDBConnection::PLATFORM_MYSQL;
- } elseif ($platform instanceof OraclePlatform) {
- return IDBConnection::PLATFORM_ORACLE;
- } elseif ($platform instanceof PostgreSQLPlatform) {
- return IDBConnection::PLATFORM_POSTGRES;
- } elseif ($platform instanceof SqlitePlatform) {
- return IDBConnection::PLATFORM_SQLITE;
- } else {
- throw new \Exception('Database ' . $platform::class . ' not supported');
- }
+ return $this->inner->getDatabaseProvider();
}
}
diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php
index 5e50d01538acc..88dbfc59c52b9 100644
--- a/lib/private/DB/ConnectionFactory.php
+++ b/lib/private/DB/ConnectionFactory.php
@@ -7,11 +7,16 @@
*/
namespace OC\DB;
-use Doctrine\Common\EventManager;
use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\DriverManager;
-use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
+use OC\DB\Logging\Middleware;
+use OC\DB\Middlewares\SetTransactionIsolationLevel;
+use OC\DB\Middlewares\SQLiteCaseSensitiveLike;
+use OC\DB\Middlewares\SQLiteJournalMode;
use OC\SystemConfig;
+use OCP\Diagnostics\IQueryLogger;
+use OCP\Profiler\IProfiler;
+use OCP\Server;
/**
* Takes care of creating and configuring Doctrine connections.
@@ -103,9 +108,17 @@ public function getDefaultConnectionParams($type) {
*/
public function getConnection($type, $additionalConnectionParams) {
$normalizedType = $this->normalizeType($type);
- $eventManager = new EventManager();
- $eventManager->addEventSubscriber(new SetTransactionIsolationLevel());
$additionalConnectionParams = array_merge($this->createConnectionParams(), $additionalConnectionParams);
+
+ $doctrineConfiguration = new Configuration();
+ $doctrineMiddlewares = $doctrineConfiguration->getMiddlewares();
+ /** @var IProfiler */
+ $profiler = Server::get(IProfiler::class);
+ if ($profiler->isEnabled()) {
+ $doctrineMiddlewares[] = new Middleware(Server::get(IQueryLogger::class));
+ }
+ $doctrineMiddlewares[] = new SetTransactionIsolationLevel();
+
switch ($normalizedType) {
case 'pgsql':
// pg_connect used by Doctrine DBAL does not support URI notation (enclosed in brackets)
@@ -117,7 +130,8 @@ public function getConnection($type, $additionalConnectionParams) {
break;
case 'oci':
- $eventManager->addEventSubscriber(new OracleSessionInit);
+ $doctrineMiddlewares[] = new \Doctrine\DBAL\Driver\OCI8\Middleware\InitializeSession();
+
// the driverOptions are unused in dbal and need to be mapped to the parameters
if (isset($additionalConnectionParams['driverOptions'])) {
$additionalConnectionParams = array_merge($additionalConnectionParams, $additionalConnectionParams['driverOptions']);
@@ -137,16 +151,26 @@ public function getConnection($type, $additionalConnectionParams) {
case 'sqlite3':
$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
- $additionalConnectionParams['platform'] = new OCSqlitePlatform();
- $eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode));
+ $doctrineMiddlewares[] = new \Doctrine\DBAL\Driver\AbstractSQLiteDriver\Middleware\EnableForeignKeys();
+ $doctrineMiddlewares[] = new SQLiteCaseSensitiveLike();
+ SQLiteJournalMode::$journalMode = $additionalConnectionParams['sqlite.journal_mode'];
+ $doctrineMiddlewares[] = new SQLiteJournalMode();
break;
}
+
+ $doctrineConfiguration->setMiddlewares($doctrineMiddlewares);
+
/** @var Connection $connection */
$connection = DriverManager::getConnection(
$additionalConnectionParams,
- new Configuration(),
- $eventManager
+ $doctrineConfiguration,
);
+
+ if ($normalizedType === 'sqlite3') {
+ $pdo = $connection->getNativeConnection();
+ $pdo->sqliteCreateFunction('md5', 'md5', 1);
+ }
+
return $connection;
}
diff --git a/lib/private/DB/DbDataCollector.php b/lib/private/DB/DbDataCollector.php
index fcaa74daeab7c..e30877fa86983 100644
--- a/lib/private/DB/DbDataCollector.php
+++ b/lib/private/DB/DbDataCollector.php
@@ -8,31 +8,22 @@
namespace OC\DB;
-use Doctrine\DBAL\Types\ConversionException;
-use Doctrine\DBAL\Types\Type;
use OC\AppFramework\Http\Request;
+use OC\Diagnostics\Query;
use OCP\AppFramework\Http\Response;
+use OCP\Diagnostics\IQueryLogger;
class DbDataCollector extends \OCP\DataCollector\AbstractDataCollector {
- protected ?BacktraceDebugStack $debugStack = null;
- private Connection $connection;
-
- /**
- * DbDataCollector constructor.
- */
- public function __construct(Connection $connection) {
- $this->connection = $connection;
- }
-
- public function setDebugStack(BacktraceDebugStack $debugStack, $name = 'default'): void {
- $this->debugStack = $debugStack;
+ public function __construct(
+ private readonly IQueryLogger $queryLogger,
+ ) {
}
/**
* @inheritDoc
*/
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void {
- $queries = $this->sanitizeQueries($this->debugStack->queries);
+ $queries = $this->sanitizeQueries($this->queryLogger->getQueries());
$this->data = [
'queries' => $queries,
@@ -55,37 +46,19 @@ private function sanitizeQueries(array $queries): array {
return $queries;
}
- private function sanitizeQuery(array $query): array {
- $query['explainable'] = true;
- $query['runnable'] = true;
- if ($query['params'] === null) {
- $query['params'] = [];
- }
- if (!\is_array($query['params'])) {
- $query['params'] = [$query['params']];
- }
- if (!\is_array($query['types'])) {
- $query['types'] = [];
- }
- foreach ($query['params'] as $j => $param) {
- $e = null;
- if (isset($query['types'][$j])) {
- // Transform the param according to the type
- $type = $query['types'][$j];
- if (\is_string($type)) {
- $type = Type::getType($type);
- }
- if ($type instanceof Type) {
- $query['types'][$j] = $type->getBindingType();
- try {
- $param = $type->convertToDatabaseValue($param, $this->connection->getDatabasePlatform());
- } catch (\TypeError $e) {
- } catch (ConversionException $e) {
- }
- }
- }
+ private function sanitizeQuery(Query $queryObject): array {
+ $query = [
+ 'sql' => $queryObject->getSql(),
+ 'params' => $queryObject->getParams() ?? [],
+ 'types' => $queryObject->getTypes() ?? [],
+ 'executionMS' => $queryObject->getDuration(),
+ 'backtrace' => $queryObject->getStacktrace(),
+ 'explainable' => true,
+ 'runnable' => true,
+ ];
- [$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param, $e);
+ foreach ($query['params'] as $j => $param) {
+ [$query['params'][$j], $explainable, $runnable] = $this->sanitizeParam($param);
if (!$explainable) {
$query['explainable'] = false;
}
@@ -105,20 +78,16 @@ private function sanitizeQuery(array $query): array {
* indicating if the original value was kept (allowing to use the sanitized
* value to explain the query).
*/
- private function sanitizeParam($var, ?\Throwable $error): array {
+ private function sanitizeParam($var): array {
if (\is_object($var)) {
- return [$o = new ObjectParameter($var, $error), false, $o->isStringable() && !$error];
- }
-
- if ($error) {
- return ['⚠ '.$error->getMessage(), false, false];
+ return [$o = new ObjectParameter($var, null), false, $o->isStringable()];
}
if (\is_array($var)) {
$a = [];
$explainable = $runnable = true;
foreach ($var as $k => $v) {
- [$value, $e, $r] = $this->sanitizeParam($v, null);
+ [$value, $e, $r] = $this->sanitizeParam($v);
$explainable = $explainable && $e;
$runnable = $runnable && $r;
$a[$k] = $value;
diff --git a/lib/private/DB/Exceptions/DbalException.php b/lib/private/DB/Exceptions/DbalException.php
index 05ea9e22a5d42..341493ba54472 100644
--- a/lib/private/DB/Exceptions/DbalException.php
+++ b/lib/private/DB/Exceptions/DbalException.php
@@ -24,6 +24,7 @@
use Doctrine\DBAL\Exception\ServerException;
use Doctrine\DBAL\Exception\SyntaxErrorException;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
use OCP\DB\Exception;
/**
@@ -83,6 +84,9 @@ public function getReason(): ?int {
/**
* Other server errors
*/
+ if ($this->original instanceof TypeNotRegistered) {
+ return parent::REASON_TYPE_UNKNOWN;
+ }
if ($this->original instanceof LockWaitTimeoutException) {
return parent::REASON_LOCK_WAIT_TIMEOUT;
}
diff --git a/lib/private/DB/Logging/Connection.php b/lib/private/DB/Logging/Connection.php
new file mode 100644
index 0000000000000..30f1e7444c57c
--- /dev/null
+++ b/lib/private/DB/Logging/Connection.php
@@ -0,0 +1,49 @@
+queryLogger,
+ $sql,
+ );
+ }
+
+ public function query(string $sql): Result {
+ $this->queryLogger->startQuery($sql);
+ $result = parent::query($sql);
+ $this->queryLogger->stopQuery();
+
+ return $result;
+ }
+
+ public function exec(string $sql): int|string {
+ $this->queryLogger->startQuery($sql);
+ $result = parent::exec($sql);
+ $this->queryLogger->stopQuery();
+
+ return $result;
+ }
+}
diff --git a/lib/private/DB/Logging/Driver.php b/lib/private/DB/Logging/Driver.php
new file mode 100644
index 0000000000000..f787ef66320b5
--- /dev/null
+++ b/lib/private/DB/Logging/Driver.php
@@ -0,0 +1,34 @@
+queryLogger,
+ );
+ }
+}
diff --git a/lib/private/DB/Logging/Middleware.php b/lib/private/DB/Logging/Middleware.php
new file mode 100644
index 0000000000000..dbfbd49fa6a1c
--- /dev/null
+++ b/lib/private/DB/Logging/Middleware.php
@@ -0,0 +1,28 @@
+queryLogger,
+ );
+ }
+}
diff --git a/lib/private/DB/Logging/Statement.php b/lib/private/DB/Logging/Statement.php
new file mode 100644
index 0000000000000..affb0cf61baf2
--- /dev/null
+++ b/lib/private/DB/Logging/Statement.php
@@ -0,0 +1,50 @@
+|array */
+ private array $params = [];
+
+ /** @var array|array */
+ private array $types = [];
+
+ public function __construct(
+ StatementInterface $statement,
+ private readonly IQueryLogger $queryLogger,
+ private readonly string $sql,
+ ) {
+ parent::__construct($statement);
+ }
+
+ public function bindValue(int|string $param, mixed $value, ParameterType $type): void {
+ $this->params[$param] = $value;
+ $this->types[$param] = $this->convertParameterTypeToJsonSerializable($type);
+
+ parent::bindValue($param, $value, $type);
+ }
+
+ public function execute(): ResultInterface {
+ $this->queryLogger->startQuery($this->sql, $this->params, $this->types);
+ $result = parent::execute();
+ $this->queryLogger->stopQuery();
+
+ return $result;
+ }
+}
diff --git a/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php b/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php
new file mode 100644
index 0000000000000..b360523002182
--- /dev/null
+++ b/lib/private/DB/Middlewares/SQLiteCaseSensitiveLike.php
@@ -0,0 +1,32 @@
+exec('PRAGMA case_sensitive_like = true');
+ return $connection;
+ }
+ };
+ }
+}
diff --git a/lib/private/DB/Middlewares/SQLiteJournalMode.php b/lib/private/DB/Middlewares/SQLiteJournalMode.php
new file mode 100644
index 0000000000000..51a0a6fb99279
--- /dev/null
+++ b/lib/private/DB/Middlewares/SQLiteJournalMode.php
@@ -0,0 +1,34 @@
+exec('PRAGMA journal_mode = ' . SQLiteJournalMode::$journalMode);
+ return $connection;
+ }
+ };
+ }
+}
diff --git a/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php b/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php
new file mode 100644
index 0000000000000..10987ef0b91b8
--- /dev/null
+++ b/lib/private/DB/Middlewares/SetTransactionIsolationLevel.php
@@ -0,0 +1,39 @@
+isConnectedToPrimary()) {
+ $connection->setTransactionIsolation(\Doctrine\DBAL\TransactionIsolationLevel::READ_COMMITTED);
+ if ($connection->getDatabasePlatform() instanceof MySQLPlatform) {
+ $connection->executeStatement('SET SESSION AUTOCOMMIT=1');
+ }
+ }
+ return $connection;
+ }
+ };
+ }
+}
diff --git a/lib/private/DB/MigrationService.php b/lib/private/DB/MigrationService.php
index 19d1b2407369b..acf060f348d43 100644
--- a/lib/private/DB/MigrationService.php
+++ b/lib/private/DB/MigrationService.php
@@ -6,20 +6,19 @@
*/
namespace OC\DB;
-use Doctrine\DBAL\Platforms\OraclePlatform;
-use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
-use Doctrine\DBAL\Types\Types;
use OC\App\InfoParser;
use OC\IntegrityCheck\Helpers\AppLocator;
use OC\Migration\SimpleOutput;
use OCP\AppFramework\App;
use OCP\AppFramework\QueryException;
use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
+use OCP\IDBConnection;
use OCP\Migration\IMigrationStep;
use OCP\Migration\IOutput;
use OCP\Server;
@@ -419,6 +418,7 @@ public function migrateSchemaOnly(string $to = 'latest'): void {
if ($toSchema instanceof SchemaWrapper) {
$this->output->debug('- Checking target database schema');
$targetSchema = $toSchema->getWrappedSchema();
+ $this->ensureVarcharLength($targetSchema);
$this->ensureUniqueNamesConstraints($targetSchema, true);
if ($this->checkOracle) {
$beforeSchema = $this->connection->createSchema();
@@ -500,6 +500,7 @@ public function executeStep($version, $schemaOnly = false) {
if ($toSchema instanceof SchemaWrapper) {
$targetSchema = $toSchema->getWrappedSchema();
+ $this->ensureVarcharLength($targetSchema);
$this->ensureUniqueNamesConstraints($targetSchema, $schemaOnly);
if ($this->checkOracle) {
$sourceSchema = $this->connection->createSchema();
@@ -565,7 +566,7 @@ public function ensureOracleConstraints(Schema $sourceSchema, Schema $targetSche
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is NotNull, but has empty string or null as default.');
}
- if ($thing->getNotnull() && $thing->getType()->getName() === Types::BOOLEAN) {
+ if ($thing->getNotnull() && Types::getType($thing->getType()) === Types::BOOLEAN) {
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is type Bool and also NotNull, so it can not store "false".');
}
@@ -576,8 +577,8 @@ public function ensureOracleConstraints(Schema $sourceSchema, Schema $targetSche
// If the column was just created OR the length changed OR the type changed
// we will NOT detect invalid length if the column is not modified
- if (($sourceColumn === null || $sourceColumn->getLength() !== $thing->getLength() || $sourceColumn->getType()->getName() !== Types::STRING)
- && $thing->getLength() > 4000 && $thing->getType()->getName() === Types::STRING) {
+ if (($sourceColumn === null || $sourceColumn->getLength() !== $thing->getLength() || Types::getType($sourceColumn->getType()) !== Types::STRING)
+ && $thing->getLength() > 4000 && Types::getType($thing->getType()) === Types::STRING) {
throw new \InvalidArgumentException('Column "' . $table->getName() . '"."' . $thing->getName() . '" is type String, but exceeding the 4.000 length limit.');
}
}
@@ -595,11 +596,11 @@ public function ensureOracleConstraints(Schema $sourceSchema, Schema $targetSche
}
$primaryKey = $table->getPrimaryKey();
- if ($primaryKey instanceof Index && (!$sourceTable instanceof Table || !$sourceTable->hasPrimaryKey())) {
+ if ($primaryKey instanceof Index && (!$sourceTable instanceof Table || !$sourceTable->getPrimaryKey())) {
$indexName = strtolower($primaryKey->getName());
$isUsingDefaultName = $indexName === 'primary';
- if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
$defaultName = $table->getName() . '_pkey';
$isUsingDefaultName = strtolower($defaultName) === $indexName;
@@ -609,7 +610,7 @@ public function ensureOracleConstraints(Schema $sourceSchema, Schema $targetSche
return $sequence->getName() !== $sequenceName;
});
}
- } elseif ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
+ } elseif ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
$defaultName = $table->getName() . '_seq';
$isUsingDefaultName = strtolower($defaultName) === $indexName;
}
@@ -712,6 +713,23 @@ public function ensureUniqueNamesConstraints(Schema $targetSchema, bool $isInsta
}
}
+ /**
+ * Ensure VARCHAR columns have a default length (required since Doctrine/DBAL 4.0)
+ *
+ * @param Schema $targetSchema
+ */
+ public function ensureVarcharLength(Schema $targetSchema): void {
+ foreach ($targetSchema->getTables() as $table) {
+ foreach ($table->getColumns() as $column) {
+ if ($column->getLength() === null) {
+ if ($column->getType()->getTypeRegistry()->lookupName($column->getType()) === 'string') {
+ $column->setLength(255);
+ }
+ }
+ }
+ }
+ }
+
protected function logErrorOrWarning(string $log): void {
if ($this->output instanceof SimpleOutput) {
$this->output->warning($log);
diff --git a/lib/private/DB/OCSqlitePlatform.php b/lib/private/DB/OCSqlitePlatform.php
deleted file mode 100644
index 3e2b10e6e4073..0000000000000
--- a/lib/private/DB/OCSqlitePlatform.php
+++ /dev/null
@@ -1,11 +0,0 @@
- $data
* @return array
*/
- private function quoteKeys(array $data) {
+ private function quoteKeys(array $data): array {
$return = [];
- $c = $this->getDatabasePlatform()->getIdentifierQuoteCharacter();
foreach ($data as $key => $value) {
- if ($key[0] !== $c) {
- $return[$this->quoteIdentifier($key)] = $value;
- } else {
- $return[$key] = $value;
- }
+ $return[$this->quoteIdentifier($key)] = $value;
}
return $return;
}
@@ -29,10 +24,8 @@ private function quoteKeys(array $data) {
/**
* {@inheritDoc}
*/
- public function insert($table, array $data, array $types = []) {
- if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
- $table = $this->quoteIdentifier($table);
- }
+ public function insert(string $table, array $data, array $types = []): int|string {
+ $table = $this->quoteIdentifier($table);
$data = $this->quoteKeys($data);
return parent::insert($table, $data, $types);
}
@@ -40,10 +33,8 @@ public function insert($table, array $data, array $types = []) {
/**
* {@inheritDoc}
*/
- public function update($table, array $data, array $criteria, array $types = []) {
- if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
- $table = $this->quoteIdentifier($table);
- }
+ public function update(string $table, array $data, array $criteria = [], array $types = []): int|string {
+ $table = $this->quoteIdentifier($table);
$data = $this->quoteKeys($data);
$criteria = $this->quoteKeys($criteria);
return parent::update($table, $data, $criteria, $types);
@@ -52,10 +43,8 @@ public function update($table, array $data, array $criteria, array $types = [])
/**
* {@inheritDoc}
*/
- public function delete($table, array $criteria, array $types = []) {
- if ($table[0] !== $this->getDatabasePlatform()->getIdentifierQuoteCharacter()) {
- $table = $this->quoteIdentifier($table);
- }
+ public function delete(string $table, array $criteria = [], array $types = []): int|string {
+ $table = $this->quoteIdentifier($table);
$criteria = $this->quoteKeys($criteria);
return parent::delete($table, $criteria);
}
@@ -65,10 +54,10 @@ public function delete($table, array $criteria, array $types = []) {
*
* @param string $table table name without the prefix
*/
- public function dropTable($table) {
+ public function dropTable($table): void {
$table = $this->tablePrefix . trim($table);
$table = $this->quoteIdentifier($table);
- $schema = $this->getSchemaManager();
+ $schema = $this->createSchemaManager();
if ($schema->tablesExist([$table])) {
$schema->dropTable($table);
}
@@ -80,10 +69,10 @@ public function dropTable($table) {
* @param string $table table name without the prefix
* @return bool
*/
- public function tableExists($table) {
+ public function tableExists($table): bool {
$table = $this->tablePrefix . trim($table);
$table = $this->quoteIdentifier($table);
- $schema = $this->getSchemaManager();
+ $schema = $this->createSchemaManager();
return $schema->tablesExist([$table]);
}
}
diff --git a/lib/private/DB/PgSqlTools.php b/lib/private/DB/PgSqlTools.php
index 35e8016191c74..d529cb26b09d5 100644
--- a/lib/private/DB/PgSqlTools.php
+++ b/lib/private/DB/PgSqlTools.php
@@ -43,7 +43,7 @@ public function resynchronizeDatabaseSequences(Connection $conn) {
return preg_match($filterExpression, $asset) !== false;
});
- foreach ($conn->getSchemaManager()->listSequences() as $sequence) {
+ foreach ($conn->createSchemaManager()->listSequences() as $sequence) {
$sequenceName = $sequence->getName();
$sqlInfo = 'SELECT table_schema, table_name, column_name
FROM information_schema.columns
diff --git a/lib/private/DB/PreparedStatement.php b/lib/private/DB/PreparedStatement.php
index 5fdfa2b03e894..84669cc992f1b 100644
--- a/lib/private/DB/PreparedStatement.php
+++ b/lib/private/DB/PreparedStatement.php
@@ -8,11 +8,10 @@
*/
namespace OC\DB;
-use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Statement;
use OCP\DB\IPreparedStatement;
use OCP\DB\IResult;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use PDO;
/**
@@ -25,6 +24,8 @@
* methods without much magic.
*/
class PreparedStatement implements IPreparedStatement {
+ use TDoctrineParameterTypeMap;
+
/** @var Statement */
private $statement;
@@ -57,16 +58,31 @@ public function fetchOne() {
return $this->getResult()->fetchOne();
}
- public function bindValue($param, $value, $type = ParameterType::STRING): bool {
- return $this->statement->bindValue($param, $value, $type);
+ public function bindValue($param, $value, $type = IQueryBuilder::PARAM_STR): bool {
+ $this->statement->bindValue($param, $value, $this->convertParameterTypeToDoctrine($type));
+ return true;
}
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool {
- return $this->statement->bindParam($param, $variable, $type, $length);
+ public function bindParam($param, &$variable, $type = IQueryBuilder::PARAM_STR, $length = null): bool {
+ if ($type !== IQueryBuilder::PARAM_STR) {
+ \OC::$server->getLogger()->warning('PreparedStatement::bindParam() is no longer supported. Use bindValue() instead.', ['exception' => new \BadMethodCallException('bindParam() is no longer supported')]);
+ }
+ $this->bindValue($param, $variable, $type);
+ return true;
}
public function execute($params = null): IResult {
- return ($this->result = new ResultAdapter($this->statement->execute($params)));
+ if ($params !== null) {
+ foreach ($params as $key => $param) {
+ if (is_int($key)) {
+ // Parameter count starts with 1
+ $this->bindValue($key + 1, $param);
+ } else {
+ $this->bindValue($key, $param);
+ }
+ }
+ }
+ return ($this->result = new ResultAdapter($this->statement->executeQuery()));
}
public function rowCount(): int {
@@ -78,6 +94,6 @@ private function getResult(): IResult {
return $this->result;
}
- throw new Exception("You have to execute the prepared statement before accessing the results");
+ throw new \Exception("You have to execute the prepared statement before accessing the results");
}
}
diff --git a/lib/private/DB/QueryBuilder/CompositeExpression.php b/lib/private/DB/QueryBuilder/CompositeExpression.php
index 493d804d54df5..1d5cc2c768fa8 100644
--- a/lib/private/DB/QueryBuilder/CompositeExpression.php
+++ b/lib/private/DB/QueryBuilder/CompositeExpression.php
@@ -30,7 +30,9 @@ public function __construct(\Doctrine\DBAL\Query\Expression\CompositeExpression
* @return \OCP\DB\QueryBuilder\ICompositeExpression
*/
public function addMultiple(array $parts = []): ICompositeExpression {
- $this->compositeExpression->addMultiple($parts);
+ foreach ($parts as $part) {
+ $this->add($part);
+ }
return $this;
}
@@ -43,8 +45,7 @@ public function addMultiple(array $parts = []): ICompositeExpression {
* @return \OCP\DB\QueryBuilder\ICompositeExpression
*/
public function add($part): ICompositeExpression {
- $this->compositeExpression->add($part);
-
+ $this->compositeExpression = $this->compositeExpression->with($part);
return $this;
}
diff --git a/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
index a7af00b9f9777..9c1ca8c7c8f37 100644
--- a/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
+++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php
@@ -63,7 +63,7 @@ public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryB
* @return \OCP\DB\QueryBuilder\ICompositeExpression
*/
public function andX(...$x): ICompositeExpression {
- $compositeExpression = call_user_func_array([$this->expressionBuilder, 'andX'], $x);
+ $compositeExpression = call_user_func_array([$this->expressionBuilder, 'and'], $x);
return new CompositeExpression($compositeExpression);
}
@@ -82,7 +82,7 @@ public function andX(...$x): ICompositeExpression {
* @return \OCP\DB\QueryBuilder\ICompositeExpression
*/
public function orX(...$x): ICompositeExpression {
- $compositeExpression = call_user_func_array([$this->expressionBuilder, 'orX'], $x);
+ $compositeExpression = call_user_func_array([$this->expressionBuilder, 'or'], $x);
return new CompositeExpression($compositeExpression);
}
@@ -288,7 +288,7 @@ public function like($x, $y, $type = null): string {
* @since 9.0.0
*/
public function iLike($x, $y, $type = null): string {
- return $this->expressionBuilder->like($this->functionBuilder->lower($x), $this->functionBuilder->lower($y));
+ return $this->expressionBuilder->like((string) $this->functionBuilder->lower($x), (string) $this->functionBuilder->lower($y));
}
/**
@@ -372,7 +372,7 @@ public function nonEmptyString($x): string {
public function bitwiseAnd($x, int $y): IQueryFunction {
return new QueryFunction($this->connection->getDatabasePlatform()->getBitAndComparisonExpression(
$this->helper->quoteColumnName($x),
- $y
+ (string) $y
));
}
@@ -387,7 +387,7 @@ public function bitwiseAnd($x, int $y): IQueryFunction {
public function bitwiseOr($x, int $y): IQueryFunction {
return new QueryFunction($this->connection->getDatabasePlatform()->getBitOrComparisonExpression(
$this->helper->quoteColumnName($x),
- $y
+ (string) $y
));
}
@@ -400,7 +400,10 @@ public function bitwiseOr($x, int $y): IQueryFunction {
* @return ILiteral
*/
public function literal($input, $type = IQueryBuilder::PARAM_STR): ILiteral {
- return new Literal($this->expressionBuilder->literal($input, $type));
+ if ($type !== IQueryBuilder::PARAM_STR) {
+ \OC::$server->getLogger()->debug('Parameter $type is no longer supported and the function only handles resulting database type string', ['exception' => new \InvalidArgumentException('$type parameter is no longer supported')]);
+ }
+ return new Literal($this->connection->getDatabasePlatform()->quoteStringLiteral((string) $input));
}
/**
diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php
index 0e7d8d2ff3eca..d163b1e32dc4a 100644
--- a/lib/private/DB/QueryBuilder/QueryBuilder.php
+++ b/lib/private/DB/QueryBuilder/QueryBuilder.php
@@ -7,10 +7,6 @@
*/
namespace OC\DB\QueryBuilder;
-use Doctrine\DBAL\Platforms\MySQLPlatform;
-use Doctrine\DBAL\Platforms\OraclePlatform;
-use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
-use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Query\QueryException;
use OC\DB\ConnectionAdapter;
use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder;
@@ -23,6 +19,7 @@
use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder;
use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder;
use OC\DB\ResultAdapter;
+use OC\DB\TDoctrineParameterTypeMap;
use OC\SystemConfig;
use OCP\DB\IResult;
use OCP\DB\QueryBuilder\ICompositeExpression;
@@ -30,9 +27,24 @@
use OCP\DB\QueryBuilder\IParameter;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\QueryBuilder\IQueryFunction;
+use OCP\IDBConnection;
use Psr\Log\LoggerInterface;
class QueryBuilder implements IQueryBuilder {
+ use TDoctrineParameterTypeMap;
+
+ /** @internal */
+ protected const SELECT = 0;
+
+ /** @internal */
+ protected const DELETE = 1;
+
+ /** @internal */
+ protected const UPDATE = 2;
+
+ /** @internal */
+ protected const INSERT = 3;
+
/** @var ConnectionAdapter */
private $connection;
@@ -49,6 +61,8 @@ class QueryBuilder implements IQueryBuilder {
/** @var bool */
private $automaticTablePrefix = true;
+ private bool $nonEmptyWhere = false;
+ private int $type = self::SELECT;
/** @var string */
protected $lastInsertedTable;
@@ -95,20 +109,12 @@ public function automaticTablePrefix($enabled) {
* @return \OCP\DB\QueryBuilder\IExpressionBuilder
*/
public function expr() {
- if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
- return new OCIExpressionBuilder($this->connection, $this);
- }
- if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
- return new PgSqlExpressionBuilder($this->connection, $this);
- }
- if ($this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
- return new MySqlExpressionBuilder($this->connection, $this);
- }
- if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
- return new SqliteExpressionBuilder($this->connection, $this);
- }
-
- return new ExpressionBuilder($this->connection, $this);
+ return match($this->connection->getDatabaseProvider()) {
+ IDBConnection::PLATFORM_ORACLE => new OCIExpressionBuilder($this->connection, $this),
+ IDBConnection::PLATFORM_POSTGRES => new PgSqlExpressionBuilder($this->connection, $this),
+ IDBConnection::PLATFORM_MYSQL => new MySqlExpressionBuilder($this->connection, $this),
+ IDBConnection::PLATFORM_SQLITE => new SqliteExpressionBuilder($this->connection, $this),
+ };
}
/**
@@ -128,13 +134,13 @@ public function expr() {
* @return \OCP\DB\QueryBuilder\IFunctionBuilder
*/
public function func() {
- if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
return new OCIFunctionBuilder($this->connection, $this, $this->helper);
}
- if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
return new SqliteFunctionBuilder($this->connection, $this, $this->helper);
}
- if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
return new PgSqlFunctionBuilder($this->connection, $this, $this->helper);
}
@@ -147,7 +153,7 @@ public function func() {
* @return integer
*/
public function getType() {
- return $this->queryBuilder->getType();
+ return $this->type;
}
/**
@@ -162,16 +168,18 @@ public function getConnection() {
/**
* Gets the state of this query builder instance.
*
- * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
+ * @return int Always returns 0 which is former `QueryBuilder::STATE_DIRTY`
+ * @deprecated 30.0.0 Function is no-op because it's removed upstream
*/
public function getState() {
- return $this->queryBuilder->getState();
+ $this->logger->debug('Relying on the query builder state is deprecated as it is an internal concern.', ['exception' => new \Exception('Table alias provided for UPDATE query')]);
+ return 0;
}
/**
* Executes this query using the bound parameters and their types.
*
- * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
+ * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeStatement}
* for insert, update and delete statements.
*
* @return IResult|int
@@ -207,24 +215,24 @@ public function execute() {
}
}
- if (!empty($this->getQueryPart('select'))) {
- $select = $this->getQueryPart('select');
- $hasSelectAll = array_filter($select, static function ($s) {
- return $s === '*';
- });
- $hasSelectSpecific = array_filter($select, static function ($s) {
- return $s !== '*';
- });
-
- if (empty($hasSelectAll) === empty($hasSelectSpecific)) {
- $exception = new QueryException('Query is selecting * and specific values in the same query. This is not supported in Oracle.');
- $this->logger->error($exception->getMessage(), [
- 'query' => $this->getSQL(),
- 'app' => 'core',
- 'exception' => $exception,
- ]);
- }
- }
+ //if (!empty($this->getQueryPart('select'))) {
+ // $select = $this->getQueryPart('select');
+ // $hasSelectAll = array_filter($select, static function ($s) {
+ // return $s === '*';
+ // });
+ // $hasSelectSpecific = array_filter($select, static function ($s) {
+ // return $s !== '*';
+ // });
+
+ // if (empty($hasSelectAll) === empty($hasSelectSpecific)) {
+ // $exception = new QueryException('Query is selecting * and specific values in the same query. This is not supported in Oracle.');
+ // $this->logger->error($exception->getMessage(), [
+ // 'query' => $this->getSQL(),
+ // 'app' => 'core',
+ // 'exception' => $exception,
+ // ]);
+ // }
+ //}
$numberOfParameters = 0;
$hasTooLargeArrayParameter = false;
@@ -254,15 +262,17 @@ public function execute() {
]);
}
- $result = $this->queryBuilder->execute();
- if (is_int($result)) {
- return $result;
+ if ($this->getType() !== self::SELECT) {
+ $result = $this->queryBuilder->executeStatement();
+ return (int) $result;
}
+
+ $result = $this->queryBuilder->executeQuery();
return new ResultAdapter($result);
}
public function executeQuery(): IResult {
- if ($this->getType() !== \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
+ if ($this->getType() !== self::SELECT) {
throw new \RuntimeException('Invalid query type, expected SELECT query');
}
@@ -280,7 +290,7 @@ public function executeQuery(): IResult {
}
public function executeStatement(): int {
- if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::SELECT) {
+ if ($this->getType() === self::SELECT) {
throw new \RuntimeException('Invalid query type, expected INSERT, DELETE or UPDATE statement');
}
@@ -332,7 +342,7 @@ public function getSQL() {
* @return $this This QueryBuilder instance.
*/
public function setParameter($key, $value, $type = null) {
- $this->queryBuilder->setParameter($key, $value, $type);
+ $this->queryBuilder->setParameter($key, $value, $this->convertParameterTypeToDoctrine($type));
return $this;
}
@@ -357,6 +367,7 @@ public function setParameter($key, $value, $type = null) {
* @return $this This QueryBuilder instance.
*/
public function setParameters(array $params, array $types = []) {
+ $types = array_map($this->convertParameterTypeToDoctrine(...), $types);
$this->queryBuilder->setParameters($params, $types);
return $this;
@@ -472,12 +483,13 @@ public function getMaxResults() {
* '@return $this This QueryBuilder instance.
*/
public function select(...$selects) {
+ $this->type = self::SELECT;
if (count($selects) === 1 && is_array($selects[0])) {
$selects = $selects[0];
}
$this->queryBuilder->select(
- $this->helper->quoteColumnNames($selects)
+ ...$this->helper->quoteColumnNames($selects)
);
return $this;
@@ -499,6 +511,7 @@ public function select(...$selects) {
* @return $this This QueryBuilder instance.
*/
public function selectAlias($select, $alias) {
+ $this->type = self::SELECT;
$this->queryBuilder->addSelect(
$this->helper->quoteColumnName($select) . ' AS ' . $this->helper->quoteColumnName($alias)
);
@@ -520,6 +533,7 @@ public function selectAlias($select, $alias) {
* @return $this This QueryBuilder instance.
*/
public function selectDistinct($select) {
+ $this->type = self::SELECT;
if (!is_array($select)) {
$select = [$select];
}
@@ -549,12 +563,13 @@ public function selectDistinct($select) {
* @return $this This QueryBuilder instance.
*/
public function addSelect(...$selects) {
+ $this->type = self::SELECT;
if (count($selects) === 1 && is_array($selects[0])) {
$selects = $selects[0];
}
$this->queryBuilder->addSelect(
- $this->helper->quoteColumnNames($selects)
+ ...$this->helper->quoteColumnNames($selects)
);
return $this;
@@ -575,11 +590,16 @@ public function addSelect(...$selects) {
* @param string $alias The table alias used in the constructed query.
*
* @return $this This QueryBuilder instance.
+ * @since 30.0.0 Alias is no longer supported
*/
public function delete($delete = null, $alias = null) {
+ if ($alias !== null) {
+ $this->logger->debug('DELETE queries with alias are no longer supported and the provided alias is ignored', ['exception' => new \InvalidArgumentException('Table alias provided for DELETE query')]);
+ }
+
+ $this->type = self::DELETE;
$this->queryBuilder->delete(
$this->getTableName($delete),
- $alias
);
return $this;
@@ -600,11 +620,16 @@ public function delete($delete = null, $alias = null) {
* @param string $alias The table alias used in the constructed query.
*
* @return $this This QueryBuilder instance.
+ * @since 30.0.0 Alias is no longer supported
*/
public function update($update = null, $alias = null) {
+ if ($alias !== null) {
+ $this->logger->debug('UPDATE queries with alias are no longer supported and the provided alias is ignored', ['exception' => new \InvalidArgumentException('Table alias provided for UPDATE query')]);
+ }
+
+ $this->type = self::UPDATE;
$this->queryBuilder->update(
$this->getTableName($update),
- $alias
);
return $this;
@@ -630,6 +655,7 @@ public function update($update = null, $alias = null) {
* @return $this This QueryBuilder instance.
*/
public function insert($insert = null) {
+ $this->type = self::INSERT;
$this->queryBuilder->insert(
$this->getTableName($insert)
);
@@ -812,9 +838,10 @@ public function set($key, $value) {
* // You can optionally programmatically build and/or expressions
* $qb = $conn->getQueryBuilder();
*
- * $or = $qb->expr()->orx();
- * $or->add($qb->expr()->eq('u.id', 1));
- * $or->add($qb->expr()->eq('u.id', 2));
+ * $or = $qb->expr()->orx(
+ * $qb->expr()->eq('u.id', 1),
+ * $qb->expr()->eq('u.id', 2),
+ * );
*
* $qb->update('users', 'u')
* ->set('u.password', md5('password'))
@@ -826,12 +853,14 @@ public function set($key, $value) {
* @return $this This QueryBuilder instance.
*/
public function where(...$predicates) {
- if ($this->getQueryPart('where') !== null && $this->systemConfig->getValue('debug', false)) {
+ if ($this->nonEmptyWhere && $this->systemConfig->getValue('debug', false)) {
// Only logging a warning, not throwing for now.
$e = new QueryException('Using where() on non-empty WHERE part, please verify it is intentional to not call andWhere() or orWhere() instead. Otherwise consider creating a new query builder object or call resetQueryPart(\'where\') first.');
$this->logger->warning($e->getMessage(), ['exception' => $e]);
}
+ $this->nonEmptyWhere = true;
+
call_user_func_array(
[$this->queryBuilder, 'where'],
$predicates
@@ -859,6 +888,7 @@ public function where(...$predicates) {
* @see where()
*/
public function andWhere(...$where) {
+ $this->nonEmptyWhere = true;
call_user_func_array(
[$this->queryBuilder, 'andWhere'],
$where
@@ -886,6 +916,7 @@ public function andWhere(...$where) {
* @see where()
*/
public function orWhere(...$where) {
+ $this->nonEmptyWhere = true;
call_user_func_array(
[$this->queryBuilder, 'orWhere'],
$where
@@ -1067,7 +1098,7 @@ public function orHaving(...$having) {
public function orderBy($sort, $order = null) {
$this->queryBuilder->orderBy(
$this->helper->quoteColumnName($sort),
- $order
+ $order ?? 'ASC'
);
return $this;
@@ -1084,7 +1115,7 @@ public function orderBy($sort, $order = null) {
public function addOrderBy($sort, $order = null) {
$this->queryBuilder->addOrderBy(
$this->helper->quoteColumnName($sort),
- $order
+ $order ?? 'ASC'
);
return $this;
@@ -1096,18 +1127,20 @@ public function addOrderBy($sort, $order = null) {
* @param string $queryPartName
*
* @return mixed
+ * @deprecated 30.0.0 The function always throws an exception
*/
public function getQueryPart($queryPartName) {
- return $this->queryBuilder->getQueryPart($queryPartName);
+ throw new \Exception('Getting query parts is no longer supported as they are implementation details.');
}
/**
* Gets all query parts.
*
* @return array
+ * @deprecated 30.0.0 The function always throws an exception
*/
public function getQueryParts() {
- return $this->queryBuilder->getQueryParts();
+ throw new \Exception('Getting query parts is no longer supported as they are implementation details.');
}
/**
@@ -1116,9 +1149,20 @@ public function getQueryParts() {
* @param array|null $queryPartNames
*
* @return $this This QueryBuilder instance.
+ * @since 30.0.0 Only null and a list of 'where'|'having'|'groupBy'|'orderBy' is supported. Everything else will throw.
*/
public function resetQueryParts($queryPartNames = null) {
- $this->queryBuilder->resetQueryParts($queryPartNames);
+ if ($queryPartNames === null) {
+ $this->queryBuilder->resetWhere();
+ $this->queryBuilder->resetHaving();
+ $this->queryBuilder->resetGroupBy();
+ $this->queryBuilder->resetOrderBy();
+ return $this;
+ }
+
+ foreach ($queryPartNames as $queryPartName) {
+ $this->resetQueryPart($queryPartName);
+ }
return $this;
}
@@ -1129,9 +1173,16 @@ public function resetQueryParts($queryPartNames = null) {
* @param string $queryPartName
*
* @return $this This QueryBuilder instance.
+ * @since 30.0.0 Only 'where'|'having'|'groupBy'|'orderBy' are supported. Everything else will throw.
*/
public function resetQueryPart($queryPartName) {
- $this->queryBuilder->resetQueryPart($queryPartName);
+ match ($queryPartName) {
+ 'where' => $this->queryBuilder->resetWhere(),
+ 'having' => $this->queryBuilder->resetHaving(),
+ 'groupBy' => $this->queryBuilder->resetGroupBy(),
+ 'orderBy' => $this->queryBuilder->resetOrderBy(),
+ default => throw new \Exception('Resetting query part "' . $queryPartName. '" is no longer supported. Please create a new QueryBuilder instead.'),
+ };
return $this;
}
@@ -1166,7 +1217,7 @@ public function resetQueryPart($queryPartName) {
* @return IParameter the placeholder name used.
*/
public function createNamedParameter($value, $type = IQueryBuilder::PARAM_STR, $placeHolder = null) {
- return new Parameter($this->queryBuilder->createNamedParameter($value, $type, $placeHolder));
+ return new Parameter($this->queryBuilder->createNamedParameter($value, $this->convertParameterTypeToDoctrine($type), $placeHolder));
}
/**
@@ -1192,7 +1243,7 @@ public function createNamedParameter($value, $type = IQueryBuilder::PARAM_STR, $
* @return IParameter
*/
public function createPositionalParameter($value, $type = IQueryBuilder::PARAM_STR) {
- return new Parameter($this->queryBuilder->createPositionalParameter($value, $type));
+ return new Parameter($this->queryBuilder->createPositionalParameter($value, $this->convertParameterTypeToDoctrine($type)));
}
/**
@@ -1248,7 +1299,7 @@ public function createFunction($call) {
* @throws \BadMethodCallException When being called before an insert query has been run.
*/
public function getLastInsertId(): int {
- if ($this->getType() === \Doctrine\DBAL\Query\QueryBuilder::INSERT && $this->lastInsertedTable) {
+ if ($this->getType() === self::INSERT && $this->lastInsertedTable) {
// lastInsertId() needs the prefix but no quotes
$table = $this->prefixTableName($this->lastInsertedTable);
return $this->connection->lastInsertId($table);
diff --git a/lib/private/DB/ResultAdapter.php b/lib/private/DB/ResultAdapter.php
index 8b004d471ec8e..158d802125aac 100644
--- a/lib/private/DB/ResultAdapter.php
+++ b/lib/private/DB/ResultAdapter.php
@@ -30,14 +30,21 @@ public function closeCursor(): bool {
}
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) {
- return $this->inner->fetch($fetchMode);
+ return match ($fetchMode) {
+ PDO::FETCH_ASSOC => $this->inner->fetchAssociative(),
+ PDO::FETCH_NUM => $this->inner->fetchNumeric(),
+ PDO::FETCH_COLUMN => $this->inner->fetchOne(),
+ default => throw new \Exception('Fetch mode needs to be assoc, num or column.'),
+ };
}
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array {
- if ($fetchMode !== PDO::FETCH_ASSOC && $fetchMode !== PDO::FETCH_NUM && $fetchMode !== PDO::FETCH_COLUMN) {
- throw new \Exception('Fetch mode needs to be assoc, num or column.');
- }
- return $this->inner->fetchAll($fetchMode);
+ return match ($fetchMode) {
+ PDO::FETCH_ASSOC => $this->inner->fetchAllAssociative(),
+ PDO::FETCH_NUM => $this->inner->fetchAllNumeric(),
+ PDO::FETCH_COLUMN => $this->inner->fetchFirstColumn(),
+ default => throw new \Exception('Fetch mode needs to be assoc, num or column.'),
+ };
}
public function fetchColumn($columnIndex = 0) {
@@ -49,6 +56,6 @@ public function fetchOne() {
}
public function rowCount(): int {
- return $this->inner->rowCount();
+ return (int) $this->inner->rowCount();
}
}
diff --git a/lib/private/DB/SQLiteMigrator.php b/lib/private/DB/SQLiteMigrator.php
index 6be17625476a3..a8b288323005d 100644
--- a/lib/private/DB/SQLiteMigrator.php
+++ b/lib/private/DB/SQLiteMigrator.php
@@ -19,8 +19,8 @@ protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $conn
foreach ($targetSchema->getTables() as $table) {
foreach ($table->getColumns() as $column) {
// column comments are not supported on SQLite
- if ($column->getComment() !== null) {
- $column->setComment(null);
+ if ($column->getComment() !== '') {
+ $column->setComment('');
}
}
}
diff --git a/lib/private/DB/SQLiteSessionInit.php b/lib/private/DB/SQLiteSessionInit.php
deleted file mode 100644
index 5fe0cb3abf64c..0000000000000
--- a/lib/private/DB/SQLiteSessionInit.php
+++ /dev/null
@@ -1,53 +0,0 @@
-caseSensitiveLike = $caseSensitiveLike;
- $this->journalMode = $journalMode;
- }
-
- /**
- * @param ConnectionEventArgs $args
- * @return void
- */
- public function postConnect(ConnectionEventArgs $args) {
- $sensitive = $this->caseSensitiveLike ? 'true' : 'false';
- $args->getConnection()->executeUpdate('PRAGMA case_sensitive_like = ' . $sensitive);
- $args->getConnection()->executeUpdate('PRAGMA journal_mode = ' . $this->journalMode);
- /** @var \Doctrine\DBAL\Driver\PDO\Connection $connection */
- $connection = $args->getConnection()->getWrappedConnection();
- $pdo = $connection->getWrappedConnection();
- $pdo->sqliteCreateFunction('md5', 'md5', 1);
- }
-
- public function getSubscribedEvents() {
- return [Events::postConnect];
- }
-}
diff --git a/lib/private/DB/SchemaWrapper.php b/lib/private/DB/SchemaWrapper.php
index 5720e10fbdbeb..59cc9e74312e5 100644
--- a/lib/private/DB/SchemaWrapper.php
+++ b/lib/private/DB/SchemaWrapper.php
@@ -8,6 +8,7 @@
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Schema\Table;
use OCP\DB\ISchemaWrapper;
class SchemaWrapper implements ISchemaWrapper {
@@ -43,26 +44,25 @@ public function performDropTableCalls() {
/**
* Gets all table names
*
- * @return array
+ * @return list
*/
- public function getTableNamesWithoutPrefix() {
- $tableNames = $this->schema->getTableNames();
- return array_map(function ($tableName) {
+ public function getTableNamesWithoutPrefix(): array {
+ return array_map(function (string $tableName) {
if (str_starts_with($tableName, $this->connection->getPrefix())) {
return substr($tableName, strlen($this->connection->getPrefix()));
}
return $tableName;
- }, $tableNames);
+ }, $this->getTableNames());
}
// Overwritten methods
/**
- * @return array
+ * @return list
*/
- public function getTableNames() {
- return $this->schema->getTableNames();
+ public function getTableNames(): array {
+ return array_map(static fn (Table $table) => $table->getName(), $this->schema->getTables());
}
/**
diff --git a/lib/private/DB/SetTransactionIsolationLevel.php b/lib/private/DB/SetTransactionIsolationLevel.php
deleted file mode 100644
index cd18c4255e339..0000000000000
--- a/lib/private/DB/SetTransactionIsolationLevel.php
+++ /dev/null
@@ -1,36 +0,0 @@
-getConnection();
- if ($connection instanceof PrimaryReadReplicaConnection && $connection->isConnectedToPrimary()) {
- $connection->setTransactionIsolation(TransactionIsolationLevel::READ_COMMITTED);
- if ($connection->getDatabasePlatform() instanceof MySQLPlatform) {
- $connection->executeStatement('SET SESSION AUTOCOMMIT=1');
- }
- }
- }
-
- public function getSubscribedEvents() {
- return [Events::postConnect];
- }
-}
diff --git a/lib/private/DB/TDoctrineParameterTypeMap.php b/lib/private/DB/TDoctrineParameterTypeMap.php
new file mode 100644
index 0000000000000..2ab7f29e4b0b5
--- /dev/null
+++ b/lib/private/DB/TDoctrineParameterTypeMap.php
@@ -0,0 +1,46 @@
+ ParameterType::NULL,
+ IQueryBuilder::PARAM_BOOL => ParameterType::BOOLEAN,
+ IQueryBuilder::PARAM_INT => ParameterType::INTEGER,
+ null,
+ IQueryBuilder::PARAM_STR => ParameterType::STRING,
+ IQueryBuilder::PARAM_LOB => ParameterType::LARGE_OBJECT,
+ IQueryBuilder::PARAM_INT_ARRAY => ArrayParameterType::INTEGER,
+ IQueryBuilder::PARAM_STR_ARRAY => ArrayParameterType::STRING,
+ // IQueryBuilder::PARAM_DATE,
+ // IQueryBuilder::PARAM_JSON,
+ default => $type,
+ };
+ }
+
+ protected function convertParameterTypeToJsonSerializable(ArrayParameterType|ParameterType|string $type): string {
+ return match($type) {
+ ParameterType::NULL => 'null',
+ ParameterType::BOOLEAN => 'boolean',
+ ParameterType::INTEGER => 'integer',
+ ArrayParameterType::INTEGER => 'integer[]',
+ ParameterType::STRING => 'string',
+ ArrayParameterType::STRING => 'string[]',
+ ParameterType::LARGE_OBJECT => 'lob',
+ IQueryBuilder::PARAM_DATE,
+ IQueryBuilder::PARAM_JSON => $type,
+ default => 'unsupported-type',
+ };
+ }
+}
diff --git a/lib/private/Diagnostics/Query.php b/lib/private/Diagnostics/Query.php
index 8161007470908..6624d13acab3a 100644
--- a/lib/private/Diagnostics/Query.php
+++ b/lib/private/Diagnostics/Query.php
@@ -1,5 +1,6 @@
sql = $sql;
- $this->params = $params;
- $this->start = $start;
- $this->stack = $stack;
+ public function __construct(
+ private readonly string $sql,
+ private readonly ?array $params,
+ private readonly ?array $types,
+ private readonly float $start,
+ private readonly array $stack,
+ ) {
}
- public function end($time) {
+ public function end(float $time): void {
$this->end = $time;
}
- /**
- * @return array
- */
- public function getParams() {
+ public function getParams(): ?array {
return $this->params;
}
- /**
- * @return string
- */
- public function getSql() {
+ public function getTypes(): ?array {
+ return $this->types;
+ }
+
+ public function getSql(): string {
return $this->sql;
}
- /**
- * @return float
- */
- public function getStart() {
+ public function getStart(): float {
return $this->start;
}
-
- /**
- * @return float
- */
- public function getDuration() {
+
+ public function getDuration(): float {
return $this->end - $this->start;
}
- public function getStartTime() {
+ public function getStartTime(): float {
return $this->start;
}
- public function getStacktrace() {
+ public function getStacktrace(): array {
return $this->stack;
}
}
diff --git a/lib/private/Diagnostics/QueryLogger.php b/lib/private/Diagnostics/QueryLogger.php
index 5efe99d1a747b..8c80207a1a8e1 100644
--- a/lib/private/Diagnostics/QueryLogger.php
+++ b/lib/private/Diagnostics/QueryLogger.php
@@ -1,5 +1,6 @@
*/
protected CappedMemoryCache $queries;
- /**
- * QueryLogger constructor.
- */
public function __construct() {
$this->queries = new CappedMemoryCache(1024);
}
- /**
- * @var bool - Module needs to be activated by some app
- */
- private $activated = false;
-
- /**
- * @inheritdoc
- */
- public function startQuery($sql, ?array $params = null, ?array $types = null) {
+ public function startQuery(string $sql, ?array $params = null, ?array $types = null): void {
if ($this->activated) {
- $this->activeQuery = new Query($sql, $params, microtime(true), $this->getStack());
+ $this->activeQuery = new Query($sql, $params, $types, microtime(true), $this->getStack());
}
}
- private function getStack() {
- $stack = debug_backtrace();
- array_shift($stack);
- array_shift($stack);
- array_shift($stack);
- return $stack;
+ private function getStack(): array {
+ return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
}
- /**
- * @inheritdoc
- */
- public function stopQuery() {
+ public function stopQuery(): void {
if ($this->activated && $this->activeQuery) {
$this->activeQuery->end(microtime(true));
$this->queries[(string)$this->index] = $this->activeQuery;
@@ -58,17 +48,11 @@ public function stopQuery() {
}
}
- /**
- * @inheritdoc
- */
- public function getQueries() {
+ public function getQueries(): array {
return $this->queries->getData();
}
- /**
- * @inheritdoc
- */
- public function activate() {
+ public function activate(): void {
$this->activated = true;
}
}
diff --git a/lib/private/DirectEditing/Manager.php b/lib/private/DirectEditing/Manager.php
index 4b8c6af31e231..47d7dc4efa789 100644
--- a/lib/private/DirectEditing/Manager.php
+++ b/lib/private/DirectEditing/Manager.php
@@ -5,7 +5,6 @@
*/
namespace OC\DirectEditing;
-use Doctrine\DBAL\FetchMode;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
@@ -210,7 +209,7 @@ public function getToken(string $token): IToken {
$query->select('*')->from(self::TABLE_TOKENS)
->where($query->expr()->eq('token', $query->createNamedParameter($token, IQueryBuilder::PARAM_STR)));
$result = $query->execute();
- if ($tokenRow = $result->fetch(FetchMode::ASSOCIATIVE)) {
+ if ($tokenRow = $result->fetch()) {
return new Token($this, $tokenRow);
}
throw new \RuntimeException('Failed to validate the token');
diff --git a/lib/private/Repair/Collation.php b/lib/private/Repair/Collation.php
index 0affb3b1ca980..a01a684151b08 100644
--- a/lib/private/Repair/Collation.php
+++ b/lib/private/Repair/Collation.php
@@ -8,7 +8,6 @@
namespace OC\Repair;
use Doctrine\DBAL\Exception\DriverException;
-use Doctrine\DBAL\Platforms\MySQLPlatform;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
@@ -50,7 +49,7 @@ public function getName() {
* Fix mime types
*/
public function run(IOutput $output) {
- if (!$this->connection->getDatabasePlatform() instanceof MySQLPlatform) {
+ if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_MYSQL) {
$output->info('Not a mysql database -> nothing to do');
return;
}
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 93aee667d18da..8c0240356cef7 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -66,7 +66,7 @@ private function createDatabase($connection) {
//we can't use OC_DB functions here because we need to connect as the administrative user.
$characterSet = $this->config->getValue('mysql.utf8mb4', false) ? 'utf8mb4' : 'utf8';
$query = "CREATE DATABASE IF NOT EXISTS `$name` CHARACTER SET $characterSet COLLATE {$characterSet}_bin;";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
} catch (\Exception $ex) {
$this->logger->error('Database creation failed.', [
'exception' => $ex,
@@ -78,7 +78,7 @@ private function createDatabase($connection) {
try {
//this query will fail if there aren't the right permissions, ignore the error
$query = "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `$name` . * TO '$user'";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
} catch (\Exception $ex) {
$this->logger->debug('Could not automatically grant privileges, this can be ignored if database user already had privileges.', [
'exception' => $ex,
@@ -100,14 +100,14 @@ private function createDBUser($connection) {
if ($connection->getDatabasePlatform() instanceof Mysql80Platform) {
$query = "CREATE USER '$name'@'localhost' IDENTIFIED WITH mysql_native_password BY '$password'";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
$query = "CREATE USER '$name'@'%' IDENTIFIED WITH mysql_native_password BY '$password'";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
} else {
$query = "CREATE USER '$name'@'localhost' IDENTIFIED BY '$password'";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
$query = "CREATE USER '$name'@'%' IDENTIFIED BY '$password'";
- $connection->executeUpdate($query);
+ $connection->executeStatement($query);
}
} catch (\Exception $ex) {
$this->logger->error('Database user creation failed.', [
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index 4ece8957ce63a..6f979c7ae672c 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -35,7 +35,7 @@ public function setupDatabase($username) {
->andWhere($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
try {
- $result = $query->execute();
+ $result = $query->executeQuery();
$canCreateRoles = $result->rowCount() > 0;
} catch (DatabaseException $e) {
$canCreateRoles = false;
@@ -103,7 +103,7 @@ private function createDatabase(Connection $connection) {
//The database does not exists... let's create it
$query = $connection->prepare("CREATE DATABASE " . addslashes($this->dbName) . " OWNER \"" . addslashes($this->dbUser) . '"');
try {
- $query->execute();
+ $query->executeStatement();
} catch (DatabaseException $e) {
$this->logger->error('Error while trying to create database', [
'exception' => $e,
@@ -112,7 +112,7 @@ private function createDatabase(Connection $connection) {
} else {
$query = $connection->prepare("REVOKE ALL PRIVILEGES ON DATABASE " . addslashes($this->dbName) . " FROM PUBLIC");
try {
- $query->execute();
+ $query->executeStatement();
} catch (DatabaseException $e) {
$this->logger->error('Error while trying to restrict database permissions', [
'exception' => $e,
@@ -127,7 +127,7 @@ private function userExists(Connection $connection) {
$query = $builder->select('*')
->from('pg_roles')
->where($builder->expr()->eq('rolname', $builder->createNamedParameter($this->dbUser)));
- $result = $query->execute();
+ $result = $query->executeQuery();
return $result->rowCount() > 0;
}
@@ -137,7 +137,7 @@ private function databaseExists(Connection $connection) {
$query = $builder->select('datname')
->from('pg_database')
->where($builder->expr()->eq('datname', $builder->createNamedParameter($this->dbName)));
- $result = $query->execute();
+ $result = $query->executeQuery();
return $result->rowCount() > 0;
}
@@ -152,10 +152,10 @@ private function createDBUser(Connection $connection) {
// create the user
$query = $connection->prepare("CREATE USER \"" . addslashes($this->dbUser) . "\" CREATEDB PASSWORD '" . addslashes($this->dbPassword) . "'");
- $query->execute();
+ $query->executeStatement();
if ($this->databaseExists($connection)) {
$query = $connection->prepare('GRANT CONNECT ON DATABASE ' . addslashes($this->dbName) . ' TO "' . addslashes($this->dbUser) . '"');
- $query->execute();
+ $query->executeStatement();
}
} catch (DatabaseException $e) {
$this->logger->error('Error while trying to create database user', [
diff --git a/lib/private/TaskProcessing/Db/TaskMapper.php b/lib/private/TaskProcessing/Db/TaskMapper.php
index 86b2a2fcc590a..da3910dcb3d89 100644
--- a/lib/private/TaskProcessing/Db/TaskMapper.php
+++ b/lib/private/TaskProcessing/Db/TaskMapper.php
@@ -59,16 +59,16 @@ public function findOldestScheduledByType(array $taskTypes, array $taskIdsToIgno
->setMaxResults(1)
->orderBy('last_updated', 'ASC');
- if (count($taskTypes) > 0) {
- $filter = $qb->expr()->orX();
+ if (!empty($taskTypes)) {
+ $filter = [];
foreach ($taskTypes as $taskType) {
- $filter->add($qb->expr()->eq('type', $qb->createPositionalParameter($taskType)));
+ $filter[] = $qb->expr()->eq('type', $qb->createPositionalParameter($taskType));
}
- $qb->andWhere($filter);
+ $qb->andWhere($qb->expr()->orX(...$filter));
}
- if (count($taskIdsToIgnore) > 0) {
+ if (!empty($taskIdsToIgnore)) {
$qb->andWhere($qb->expr()->notIn('id', $qb->createNamedParameter($taskIdsToIgnore, IQueryBuilder::PARAM_INT_ARRAY)));
}
diff --git a/lib/public/DB/Exception.php b/lib/public/DB/Exception.php
index 6b908382aeab6..b77dca9f0f177 100644
--- a/lib/public/DB/Exception.php
+++ b/lib/public/DB/Exception.php
@@ -127,6 +127,13 @@ class Exception extends BaseException {
*/
public const REASON_LOCK_WAIT_TIMEOUT = 15;
+ /**
+ * The lock wait timeout was exceeded
+ *
+ * @since 30.0.0
+ */
+ public const REASON_TYPE_UNKNOWN = 16;
+
/**
* @return int|null
* @psalm-return Exception::REASON_*
diff --git a/lib/public/DB/IPreparedStatement.php b/lib/public/DB/IPreparedStatement.php
index 887451a1caf87..e2a72bd4a27ed 100644
--- a/lib/public/DB/IPreparedStatement.php
+++ b/lib/public/DB/IPreparedStatement.php
@@ -9,7 +9,7 @@
namespace OCP\DB;
use Doctrine\DBAL\Exception;
-use Doctrine\DBAL\ParameterType;
+use OCP\DB\QueryBuilder\IQueryBuilder;
use PDO;
/**
@@ -80,7 +80,7 @@ public function fetchOne();
*
* @since 21.0.0
*/
- public function bindValue($param, $value, $type = ParameterType::STRING): bool;
+ public function bindValue($param, $value, $type = IQueryBuilder::PARAM_STR): bool;
/**
* @param int|string $param
@@ -93,8 +93,9 @@ public function bindValue($param, $value, $type = ParameterType::STRING): bool;
* @throws Exception
*
* @since 21.0.0
+ * @deprecated 30.0.0 Use {@see self::bindValue()} instead
*/
- public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool;
+ public function bindParam($param, &$variable, $type = IQueryBuilder::PARAM_STR, $length = null): bool;
/**
* @param mixed[]|null $params
diff --git a/lib/public/DB/IResult.php b/lib/public/DB/IResult.php
index 347919ab3366b..ccff8c0cd185c 100644
--- a/lib/public/DB/IResult.php
+++ b/lib/public/DB/IResult.php
@@ -69,9 +69,10 @@ public function fetchColumn();
public function fetchOne();
/**
- * @return int
+ * @return int If the result is bigger than PHP_INT_MAX, PHP_INT_MAX is returned
*
* @since 21.0.0
+ * @since 30.0.0 If the result is bigger than PHP_INT_MAX, PHP_INT_MAX is returned
*/
public function rowCount(): int;
}
diff --git a/lib/public/DB/QueryBuilder/IExpressionBuilder.php b/lib/public/DB/QueryBuilder/IExpressionBuilder.php
index 6df9949cb75c2..d0f89b5580024 100644
--- a/lib/public/DB/QueryBuilder/IExpressionBuilder.php
+++ b/lib/public/DB/QueryBuilder/IExpressionBuilder.php
@@ -403,6 +403,7 @@ public function bitwiseOr($x, int $y): IQueryFunction;
*
* @return ILiteral
* @since 8.2.0
+ * @deprecated 30.0.0 Only strings are supported as database type in the end and the $type parameter is ignored going forward
*
* @psalm-taint-sink sql $input
* @psalm-taint-sink sql $type
diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php
index 94ab796adf4c0..ee992493738c8 100644
--- a/lib/public/DB/QueryBuilder/IQueryBuilder.php
+++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php
@@ -23,23 +23,23 @@ interface IQueryBuilder {
/**
* @since 9.0.0
*/
- public const PARAM_NULL = ParameterType::NULL;
+ public const PARAM_NULL = 0; // Translates to ParameterType::NULL;
/**
* @since 9.0.0
*/
- public const PARAM_BOOL = ParameterType::BOOLEAN;
+ public const PARAM_BOOL = 4; // Translates to ParameterType::BOOLEAN;
/**
* @since 9.0.0
*/
- public const PARAM_INT = ParameterType::INTEGER;
+ public const PARAM_INT = 1; // Translates to ParameterType::INTEGER;
/**
* @since 9.0.0
*/
- public const PARAM_STR = ParameterType::STRING;
+ public const PARAM_STR = 2; // Translates to ParameterType::STRING;
/**
* @since 9.0.0
*/
- public const PARAM_LOB = ParameterType::LARGE_OBJECT;
+ public const PARAM_LOB = 3; // Translates to ParameterType::LARGE_OBJECT;
/**
* @since 9.0.0
*/
@@ -53,11 +53,11 @@ interface IQueryBuilder {
/**
* @since 9.0.0
*/
- public const PARAM_INT_ARRAY = ArrayParameterType::INTEGER;
+ public const PARAM_INT_ARRAY = 100; // Translates to ArrayParameterType::INTEGER;
/**
* @since 9.0.0
*/
- public const PARAM_STR_ARRAY = ArrayParameterType::STRING;
+ public const PARAM_STR_ARRAY = 101; // Translates to ArrayParameterType::STRING;
/**
* @since 24.0.0 Indicates how many rows can be deleted at once with MySQL
@@ -391,8 +391,8 @@ public function addSelect(...$select);
*
*
* $qb = $conn->getQueryBuilder()
- * ->delete('users', 'u')
- * ->where('u.id = :user_id');
+ * ->delete('users')
+ * ->where('id = :user_id');
* ->setParameter(':user_id', 1);
*
*
@@ -401,6 +401,7 @@ public function addSelect(...$select);
*
* @return $this This QueryBuilder instance.
* @since 8.2.0
+ * @since 30.0.0 Alias is no longer supported
*
* @psalm-taint-sink sql $delete
*/
@@ -412,9 +413,10 @@ public function delete($delete = null, $alias = null);
*
*
* $qb = $conn->getQueryBuilder()
- * ->update('users', 'u')
- * ->set('u.password', md5('password'))
- * ->where('u.id = ?');
+ * ->update('users')
+ * ->set('email', ':email')
+ * ->where('id = :user_id');
+ * ->setParameter(':user_id', 1);
*
*
* @param string $update The table whose rows are subject to the update.
@@ -422,6 +424,7 @@ public function delete($delete = null, $alias = null);
*
* @return $this This QueryBuilder instance.
* @since 8.2.0
+ * @since 30.0.0 Alias is no longer supported
*
* @psalm-taint-sink sql $update
*/
@@ -605,9 +608,10 @@ public function set($key, $value);
* // You can optionally programmatically build and/or expressions
* $qb = $conn->getQueryBuilder();
*
- * $or = $qb->expr()->orx();
- * $or->add($qb->expr()->eq('u.id', 1));
- * $or->add($qb->expr()->eq('u.id', 2));
+ * $or = $qb->expr()->orx(
+ * $qb->expr()->eq('u.id', 1),
+ * $qb->expr()->eq('u.id', 2),
+ * );
*
* $qb->update('users', 'u')
* ->set('u.password', md5('password'))
@@ -833,6 +837,7 @@ public function addOrderBy($sort, $order = null);
*
* @return mixed
* @since 8.2.0
+ * @deprecated 30.0.0 The function always throws an exception
*/
public function getQueryPart($queryPartName);
@@ -841,6 +846,7 @@ public function getQueryPart($queryPartName);
*
* @return array
* @since 8.2.0
+ * @deprecated 30.0.0 The function always throws an exception
*/
public function getQueryParts();
@@ -851,6 +857,7 @@ public function getQueryParts();
*
* @return $this This QueryBuilder instance.
* @since 8.2.0
+ * @since 30.0.0 Only null and a list of 'where'|'having'|'groupBy'|'orderBy' is supported. Everything else will throw.
*/
public function resetQueryParts($queryPartNames = null);
@@ -861,6 +868,7 @@ public function resetQueryParts($queryPartNames = null);
*
* @return $this This QueryBuilder instance.
* @since 8.2.0
+ * @since 30.0.0 Only 'where'|'having'|'groupBy'|'orderBy' are supported. Everything else will throw.
*/
public function resetQueryPart($queryPartName);
diff --git a/lib/public/DB/Types.php b/lib/public/DB/Types.php
index 414d81a24c8b2..5a496c132d3a6 100644
--- a/lib/public/DB/Types.php
+++ b/lib/public/DB/Types.php
@@ -8,6 +8,10 @@
*/
namespace OCP\DB;
+use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
+use Doctrine\DBAL\Types\Type;
+use OC\DB\Exceptions\DbalException;
+
/**
* Database types supported by Nextcloud's DBs
*
@@ -99,4 +103,36 @@ final class Types {
* @since 24.0.0
*/
public const JSON = 'json';
+
+ /**
+ * @param Type $type
+ * @return string
+ * @throws Exception
+ * @since 30.0.0
+ */
+ public static function getType(Type $type): string {
+ try {
+ $doctrineType = $type->getTypeRegistry()->lookupName($type);
+ } catch (\Doctrine\DBAL\Exception $e) {
+ throw DbalException::wrap($e);
+ }
+
+ return match ($doctrineType) {
+ self::BIGINT,
+ self::BINARY,
+ self::BLOB,
+ self::BOOLEAN,
+ self::DATE,
+ self::DATETIME,
+ self::DECIMAL,
+ self::FLOAT,
+ self::INTEGER,
+ self::SMALLINT,
+ self::STRING,
+ self::TEXT,
+ self::TIME,
+ self::JSON => $doctrineType,
+ default => throw DbalException::wrap(new TypeNotRegistered(sprintf('Type of the class %s is not registered.', $doctrineType))),
+ };
+ }
}
diff --git a/lib/public/Diagnostics/IQuery.php b/lib/public/Diagnostics/IQuery.php
index 3fe39be27bd99..0c717f547d0ac 100644
--- a/lib/public/Diagnostics/IQuery.php
+++ b/lib/public/Diagnostics/IQuery.php
@@ -1,5 +1,6 @@
getColumn($columnName);
- if ($column->getType()->getName() !== Types::BIGINT) {
+ if (Types::getType($column->getType()) !== Types::BIGINT) {
$column->setType(Type::getType(Types::BIGINT));
$column->setOptions(['length' => 20]);
}
diff --git a/tests/lib/DB/Exception/DbalExceptionTest.php b/tests/lib/DB/Exception/DbalExceptionTest.php
index 470beff9080b9..ec9a1f9716cde 100644
--- a/tests/lib/DB/Exception/DbalExceptionTest.php
+++ b/tests/lib/DB/Exception/DbalExceptionTest.php
@@ -7,7 +7,6 @@
*/
namespace Test\DB\Exception;
-use Doctrine\DBAL\ConnectionException;
use Doctrine\DBAL\Driver\Exception as TheDriverException;
use Doctrine\DBAL\Exception\ConstraintViolationException;
use Doctrine\DBAL\Exception\DatabaseObjectExistsException;
@@ -15,9 +14,10 @@
use Doctrine\DBAL\Exception\DeadlockException;
use Doctrine\DBAL\Exception\DriverException;
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
-use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\Exception\InvalidFieldNameException;
+use Doctrine\DBAL\Exception\InvalidWrapperClass;
use Doctrine\DBAL\Exception\LockWaitTimeoutException;
+use Doctrine\DBAL\Exception\NoActiveTransaction;
use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
use Doctrine\DBAL\Exception\ServerException;
@@ -63,12 +63,12 @@ public function dataDriverException(): array {
}
public function testConnectionException(): void {
- $result = DbalException::wrap(ConnectionException::noActiveTransaction());
+ $result = DbalException::wrap(NoActiveTransaction::new());
$this->assertSame(DbalException::REASON_CONNECTION_LOST, $result->getReason());
}
public function testInvalidArgumentException(): void {
- $result = DbalException::wrap(InvalidArgumentException::fromEmptyCriteria());
+ $result = DbalException::wrap(InvalidWrapperClass::new('A'));
$this->assertSame(DbalException::REASON_INVALID_ARGUMENT, $result->getReason());
}
}
diff --git a/tests/lib/DB/MigrationsTest.php b/tests/lib/DB/MigrationsTest.php
index 6cd489258bffe..e1432e59964d5 100644
--- a/tests/lib/DB/MigrationsTest.php
+++ b/tests/lib/DB/MigrationsTest.php
@@ -8,13 +8,11 @@
namespace Test\DB;
-use Doctrine\DBAL\Platforms\OraclePlatform;
-use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Schema\Exception\TableDoesNotExist;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
-use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
@@ -100,7 +98,7 @@ public function testExecuteStepWithSchemaChange() {
->method('migrateToSchema');
$wrappedSchema = $this->createMock(Schema::class);
- $wrappedSchema->expects($this->exactly(2))
+ $wrappedSchema->expects($this->any())
->method('getTables')
->willReturn([]);
$wrappedSchema->expects($this->exactly(2))
@@ -273,7 +271,7 @@ public function testEnsureOracleConstraintsValid() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -316,7 +314,7 @@ public function testEnsureOracleConstraintsValidWithPrimaryKey() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -326,9 +324,9 @@ public function testEnsureOracleConstraintsValidWithPrimaryKey() {
public function testEnsureOracleConstraintsValidWithPrimaryKeyDefault() {
$defaultName = 'PRIMARY';
- if ($this->db->getDatabasePlatform() instanceof PostgreSqlPlatform) {
+ if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
$defaultName = \str_repeat('a', 26) . '_' . \str_repeat('b', 30) . '_seq';
- } elseif ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
+ } elseif ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
$defaultName = \str_repeat('a', 26) . '_seq';
}
@@ -369,7 +367,7 @@ public function testEnsureOracleConstraintsValidWithPrimaryKeyDefault() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -394,7 +392,7 @@ public function testEnsureOracleConstraintsTooLongTableName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -407,9 +405,9 @@ public function testEnsureOracleConstraintsTooLongPrimaryWithDefault() {
$this->expectException(\InvalidArgumentException::class);
$defaultName = 'PRIMARY';
- if ($this->db->getDatabasePlatform() instanceof PostgreSqlPlatform) {
+ if ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_POSTGRES) {
$defaultName = \str_repeat('a', 27) . '_' . \str_repeat('b', 30) . '_seq';
- } elseif ($this->db->getDatabasePlatform() instanceof OraclePlatform) {
+ } elseif ($this->db->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
$defaultName = \str_repeat('a', 27) . '_seq';
}
@@ -447,7 +445,7 @@ public function testEnsureOracleConstraintsTooLongPrimaryWithDefault() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -490,7 +488,7 @@ public function testEnsureOracleConstraintsTooLongPrimaryWithName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -524,7 +522,7 @@ public function testEnsureOracleConstraintsTooLongColumnName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -561,7 +559,7 @@ public function testEnsureOracleConstraintsTooLongIndexName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -601,7 +599,7 @@ public function testEnsureOracleConstraintsTooLongForeignKeyName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -642,7 +640,7 @@ public function testEnsureOracleConstraintsNoPrimaryKey() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -670,7 +668,7 @@ public function testEnsureOracleConstraintsTooLongSequenceName() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -710,7 +708,7 @@ public function testEnsureOracleConstraintsBooleanNotNull() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
@@ -750,7 +748,7 @@ public function testEnsureOracleConstraintsStringLength4000() {
$sourceSchema = $this->createMock(Schema::class);
$sourceSchema->expects($this->any())
->method('getTable')
- ->willThrowException(new SchemaException());
+ ->willThrowException(TableDoesNotExist::new('a'));
$sourceSchema->expects($this->any())
->method('hasSequence')
->willReturn(false);
diff --git a/tests/lib/DB/MigratorTest.php b/tests/lib/DB/MigratorTest.php
index eaa6540b93bd6..2174ec543b8d1 100644
--- a/tests/lib/DB/MigratorTest.php
+++ b/tests/lib/DB/MigratorTest.php
@@ -1,5 +1,6 @@
connection->getDatabasePlatform();
- $random = \OC::$server->get(ISecureRandom::class);
$dispatcher = \OC::$server->get(\OCP\EventDispatcher\IEventDispatcher::class);
- if ($platform instanceof SqlitePlatform) {
+ if ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_SQLITE) {
return new SQLiteMigrator($this->connection, $this->config, $dispatcher);
- } elseif ($platform instanceof OraclePlatform) {
+ } elseif ($this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
return new OracleMigrator($this->connection, $this->config, $dispatcher);
}
return new Migrator($this->connection, $this->config, $dispatcher);
}
- private function getUniqueTableName() {
+ private function getUniqueTableName(): string {
return strtolower($this->getUniqueID($this->config->getSystemValueString('dbtableprefix', 'oc_') . 'test_'));
}
protected function tearDown(): void {
// Try to delete if exists (IF EXISTS NOT SUPPORTED IN ORACLE)
try {
- $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableNameTmp));
+ $this->connection->executeStatement('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableNameTmp));
} catch (Exception $e) {
}
try {
- $this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName));
+ $this->connection->executeStatement('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName));
} catch (Exception $e) {
}
parent::tearDown();
@@ -88,17 +89,17 @@ protected function tearDown(): void {
/**
* @return \Doctrine\DBAL\Schema\Schema[]
*/
- private function getDuplicateKeySchemas() {
+ private function getDuplicateKeySchemas(): array {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer');
- $table->addColumn('name', 'string');
+ $table->addColumn('id', Types::INTEGER);
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->addIndex(['id'], $this->tableName . '_id');
$endSchema = new Schema([], [], $this->getSchemaConfig());
$table = $endSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer');
- $table->addColumn('name', 'string');
+ $table->addColumn('id', Types::INTEGER);
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->addUniqueIndex(['id'], $this->tableName . '_id');
return [$startSchema, $endSchema];
@@ -107,30 +108,30 @@ private function getDuplicateKeySchemas() {
/**
* @return \Doctrine\DBAL\Schema\Schema[]
*/
- private function getChangedTypeSchema($from, $to) {
+ private function getChangedTypeSchema(string $from, string $to): array {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
$table->addColumn('id', $from);
- $table->addColumn('name', 'string');
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->addIndex(['id'], $this->tableName . '_id');
$endSchema = new Schema([], [], $this->getSchemaConfig());
$table = $endSchema->createTable($this->tableName);
$table->addColumn('id', $to);
- $table->addColumn('name', 'string');
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->addIndex(['id'], $this->tableName . '_id');
return [$startSchema, $endSchema];
}
- private function getSchemaConfig() {
+ private function getSchemaConfig(): SchemaConfig {
$config = new SchemaConfig();
$config->setName($this->connection->getDatabase());
return $config;
}
- public function testUpgrade() {
+ public function testUpgrade(): void {
[$startSchema, $endSchema] = $this->getDuplicateKeySchemas();
$migrator = $this->getMigrator();
$migrator->migrate($startSchema);
@@ -143,7 +144,7 @@ public function testUpgrade() {
$this->addToAssertionCount(1);
}
- public function testUpgradeDifferentPrefix() {
+ public function testUpgradeDifferentPrefix(): void {
$oldTablePrefix = $this->config->getSystemValueString('dbtableprefix', 'oc_');
$this->config->setSystemValue('dbtableprefix', 'ownc_');
@@ -163,7 +164,7 @@ public function testUpgradeDifferentPrefix() {
$this->config->setSystemValue('dbtableprefix', $oldTablePrefix);
}
- public function testInsertAfterUpgrade() {
+ public function testInsertAfterUpgrade(): void {
[$startSchema, $endSchema] = $this->getDuplicateKeySchemas();
$migrator = $this->getMigrator();
$migrator->migrate($startSchema);
@@ -180,16 +181,16 @@ public function testInsertAfterUpgrade() {
}
}
- public function testAddingPrimaryKeyWithAutoIncrement() {
+ public function testAddingPrimaryKeyWithAutoIncrement(): void {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer');
- $table->addColumn('name', 'string');
+ $table->addColumn('id', Types::INTEGER);
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$endSchema = new Schema([], [], $this->getSchemaConfig());
$table = $endSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true]);
- $table->addColumn('name', 'string');
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->setPrimaryKey(['id']);
$migrator = $this->getMigrator();
@@ -200,17 +201,17 @@ public function testAddingPrimaryKeyWithAutoIncrement() {
$this->addToAssertionCount(1);
}
- public function testReservedKeywords() {
+ public function testReservedKeywords(): void {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true]);
- $table->addColumn('user', 'string', ['length' => 255]);
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
+ $table->addColumn('user', Types::STRING, ['length' => 255]);
$table->setPrimaryKey(['id']);
$endSchema = new Schema([], [], $this->getSchemaConfig());
$table = $endSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true]);
- $table->addColumn('user', 'string', ['length' => 64]);
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
+ $table->addColumn('user', Types::STRING, ['length' => 64]);
$table->setPrimaryKey(['id']);
$migrator = $this->getMigrator();
@@ -224,17 +225,17 @@ public function testReservedKeywords() {
/**
* Test for nextcloud/server#36803
*/
- public function testColumnCommentsInUpdate() {
+ public function testColumnCommentsInUpdate(): void {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true, 'comment' => 'foo']);
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'comment' => 'foo']);
$table->setPrimaryKey(['id']);
$endSchema = new Schema([], [], $this->getSchemaConfig());
$table = $endSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true, 'comment' => 'foo']);
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true, 'comment' => 'foo']);
// Assert adding comments on existing tables work (or at least does not throw)
- $table->addColumn('time', 'integer', ['comment' => 'unix-timestamp', 'notnull' => false]);
+ $table->addColumn('time', Types::INTEGER, ['comment' => 'unix-timestamp', 'notnull' => false]);
$table->setPrimaryKey(['id']);
$migrator = $this->getMigrator();
@@ -245,17 +246,17 @@ public function testColumnCommentsInUpdate() {
$this->addToAssertionCount(1);
}
- public function testAddingForeignKey() {
+ public function testAddingForeignKey(): void {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
- $table->addColumn('id', 'integer', ['autoincrement' => true]);
- $table->addColumn('name', 'string');
+ $table->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
+ $table->addColumn('name', Types::STRING, ['length' => 255]);
$table->setPrimaryKey(['id']);
$fkName = "fkc";
$tableFk = $startSchema->createTable($this->tableNameTmp);
- $tableFk->addColumn('fk_id', 'integer');
- $tableFk->addColumn('name', 'string');
+ $tableFk->addColumn('fk_id', Types::INTEGER);
+ $tableFk->addColumn('name', Types::STRING, ['length' => 255]);
$tableFk->addForeignKeyConstraint($this->tableName, ['fk_id'], ['id'], [], $fkName);
$migrator = $this->getMigrator();
@@ -267,40 +268,44 @@ public function testAddingForeignKey() {
public function dataNotNullEmptyValuesFailOracle(): array {
return [
- [ParameterType::BOOLEAN, true, Types::BOOLEAN, false],
- [ParameterType::BOOLEAN, false, Types::BOOLEAN, true],
+ [IQueryBuilder::PARAM_BOOL, true, Types::BOOLEAN, false],
+ [IQueryBuilder::PARAM_BOOL, false, Types::BOOLEAN, true],
- [ParameterType::STRING, 'foo', Types::STRING, false],
- [ParameterType::STRING, '', Types::STRING, true],
+ [IQueryBuilder::PARAM_STR, 'foo', Types::STRING, false],
+ [IQueryBuilder::PARAM_STR, '', Types::STRING, true],
- [ParameterType::INTEGER, 1234, Types::INTEGER, false],
- [ParameterType::INTEGER, 0, Types::INTEGER, false], // Integer 0 is not stored as Null and therefor works
+ [IQueryBuilder::PARAM_INT, 1234, Types::INTEGER, false],
+ [IQueryBuilder::PARAM_INT, 0, Types::INTEGER, false], // Integer 0 is not stored as Null and therefor works
- [ParameterType::STRING, '{"a": 2}', Types::JSON, false],
+ [IQueryBuilder::PARAM_JSON, '{"a": 2}', Types::JSON, false],
];
}
/**
* @dataProvider dataNotNullEmptyValuesFailOracle
*
- * @param int $parameterType
+ * @param int|string $parameterType
* @param bool|int|string $value
* @param string $columnType
* @param bool $oracleThrows
*/
- public function testNotNullEmptyValuesFailOracle(int $parameterType, $value, string $columnType, bool $oracleThrows): void {
+ public function testNotNullEmptyValuesFailOracle(int|string $parameterType, bool|int|string $value, string $columnType, bool $oracleThrows): void {
$startSchema = new Schema([], [], $this->getSchemaConfig());
$table = $startSchema->createTable($this->tableName);
$table->addColumn('id', Types::BIGINT);
- $table->addColumn('will_it_blend', $columnType, [
+ $options = $columnType === Types::STRING ? [
+ 'length' => 255,
+ 'notnull' => true,
+ ] : [
'notnull' => true,
- ]);
+ ];
+ $table->addColumn('will_it_blend', $columnType, $options);
$table->addIndex(['id'], $this->tableName . '_id');
$migrator = $this->getMigrator();
$migrator->migrate($startSchema);
- if ($oracleThrows && $this->connection->getDatabasePlatform() instanceof OraclePlatform) {
+ if ($oracleThrows && $this->connection->getDatabaseProvider() === IDBConnection::PLATFORM_ORACLE) {
// Oracle can not store false|empty string in notnull columns
$this->expectException(\Doctrine\DBAL\Exception\NotNullConstraintViolationException::class);
}
@@ -308,7 +313,7 @@ public function testNotNullEmptyValuesFailOracle(int $parameterType, $value, str
$this->connection->insert(
$this->tableName,
['id' => 1, 'will_it_blend' => $value],
- ['id' => ParameterType::INTEGER, 'will_it_blend' => $parameterType],
+ ['id' => ParameterType::INTEGER, 'will_it_blend' => $this->convertParameterTypeToDoctrine($parameterType)],
);
$this->addToAssertionCount(1);
diff --git a/tests/lib/DB/OCPostgreSqlPlatformTest.php b/tests/lib/DB/OCPostgreSqlPlatformTest.php
index 4f83e866a7c51..73e7cb4ace038 100644
--- a/tests/lib/DB/OCPostgreSqlPlatformTest.php
+++ b/tests/lib/DB/OCPostgreSqlPlatformTest.php
@@ -1,4 +1,6 @@
createTableAndColumn($sourceSchema, Types::INTEGER);
$this->createTableAndColumn($targetSchema, Types::BIGINT);
- $comparator = new Comparator();
- $diff = $comparator->compare($sourceSchema, $targetSchema);
- $sqlStatements = $diff->toSql($platform);
+ $comparator = new Comparator($platform);
+ $diff = $comparator->compareSchemas($sourceSchema, $targetSchema);
+ $sqlStatements = $platform->getAlterSchemaSQL($diff);
$this->assertContains(
'ALTER TABLE poor_yorick ALTER id TYPE BIGINT',
- $sqlStatements,
- true
+ $sqlStatements
);
$this->assertNotContains(
'ALTER TABLE poor_yorick ALTER id DROP DEFAULT',
- $sqlStatements,
- true
+ $sqlStatements
);
}
- protected function createTableAndColumn($schema, $type) {
+ protected function createTableAndColumn(Schema $schema, string $type): void {
$table = $schema->createTable("poor_yorick");
$table->addColumn('id', $type, [
'autoincrement' => true,
diff --git a/tests/lib/DB/QueryBuilder/ExpressionBuilderDBTest.php b/tests/lib/DB/QueryBuilder/ExpressionBuilderDBTest.php
index 671bcfc209ee2..efc9be6f80044 100644
--- a/tests/lib/DB/QueryBuilder/ExpressionBuilderDBTest.php
+++ b/tests/lib/DB/QueryBuilder/ExpressionBuilderDBTest.php
@@ -9,6 +9,7 @@
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Types;
use OC\DB\QueryBuilder\Literal;
+use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IConfig;
use OCP\Server;
@@ -215,7 +216,11 @@ protected function prepareTestingTable(): void {
try {
$schema->getTable($prefix . 'testing');
$this->connection->getQueryBuilder()->delete('testing')->executeStatement();
- } catch (SchemaException $e) {
+ } catch (SchemaException|Exception $e) {
+ if ($e instanceof Exception && $e->getReason() !== Exception::REASON_DATABASE_OBJECT_NOT_FOUND) {
+ throw $e;
+ }
+
$this->schemaSetup = true;
$table = $schema->createTable($prefix . 'testing');
$table->addColumn('id', Types::BIGINT, [
diff --git a/tests/lib/DB/QueryBuilder/QueryBuilderTest.php b/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
index 96cde8ba1f9e8..55ec87f915674 100644
--- a/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
+++ b/tests/lib/DB/QueryBuilder/QueryBuilderTest.php
@@ -407,154 +407,99 @@ public function testAddSelect($selectArguments, $expected, $expectedLiteral = ''
$this->deleteTestingRows();
}
- public function dataDelete() {
+ public function dataDelete(): array {
return [
- ['data', null, ['table' => '`*PREFIX*data`', 'alias' => null], '`*PREFIX*data`'],
- ['data', 't', ['table' => '`*PREFIX*data`', 'alias' => 't'], '`*PREFIX*data` t'],
+ ['data', null, '`*PREFIX*data`'],
+ ['data', 't', '`*PREFIX*data`'],
];
}
/**
* @dataProvider dataDelete
- *
- * @param string $tableName
- * @param string $tableAlias
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testDelete($tableName, $tableAlias, $expectedQueryPart, $expectedQuery) {
+ public function testDelete(string $tableName, ?string $tableAlias, string $expectedQuery): void {
$this->queryBuilder->delete($tableName, $tableAlias);
- $this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('from')
- );
-
$this->assertSame(
'DELETE FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataUpdate() {
+ public function dataUpdate(): array {
return [
- ['data', null, ['table' => '`*PREFIX*data`', 'alias' => null], '`*PREFIX*data`'],
- ['data', 't', ['table' => '`*PREFIX*data`', 'alias' => 't'], '`*PREFIX*data` t'],
+ ['data', null, '`*PREFIX*data`'],
+ ['data', 't', '`*PREFIX*data`'],
];
}
/**
* @dataProvider dataUpdate
- *
- * @param string $tableName
- * @param string $tableAlias
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testUpdate($tableName, $tableAlias, $expectedQueryPart, $expectedQuery) {
+ public function testUpdate(string $tableName, ?string $tableAlias, string $expectedQuery): void {
$this->queryBuilder->update($tableName, $tableAlias);
- $this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('from')
- );
-
$this->assertSame(
'UPDATE ' . $expectedQuery . ' SET ',
$this->queryBuilder->getSQL()
);
}
- public function dataInsert() {
+ public function dataInsert(): array {
return [
- ['data', ['table' => '`*PREFIX*data`'], '`*PREFIX*data`'],
+ ['data', '`*PREFIX*data`'],
];
}
/**
* @dataProvider dataInsert
- *
- * @param string $tableName
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testInsert($tableName, $expectedQueryPart, $expectedQuery) {
+ public function testInsert(string $tableName, string $expectedQuery): void {
$this->queryBuilder->insert($tableName);
- $this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('from')
- );
-
$this->assertSame(
'INSERT INTO ' . $expectedQuery . ' () VALUES()',
$this->queryBuilder->getSQL()
);
}
- public function dataFrom() {
+ public function dataFrom(): array {
$config = $this->createMock(SystemConfig::class);
$logger = $this->createMock(LoggerInterface::class);
$qb = new QueryBuilder(\OC::$server->getDatabaseConnection(), $config, $logger);
return [
- [$qb->createFunction('(' . $qb->select('*')->from('test')->getSQL() . ')'), 'q', null, null, [
- ['table' => '(SELECT * FROM `*PREFIX*test`)', 'alias' => '`q`']
- ], '(SELECT * FROM `*PREFIX*test`) `q`'],
- ['data', null, null, null, [['table' => '`*PREFIX*data`', 'alias' => null]], '`*PREFIX*data`'],
- ['data', 't', null, null, [['table' => '`*PREFIX*data`', 'alias' => '`t`']], '`*PREFIX*data` `t`'],
- ['data1', null, 'data2', null, [
- ['table' => '`*PREFIX*data1`', 'alias' => null],
- ['table' => '`*PREFIX*data2`', 'alias' => null]
- ], '`*PREFIX*data1`, `*PREFIX*data2`'],
- ['data', 't1', 'data', 't2', [
- ['table' => '`*PREFIX*data`', 'alias' => '`t1`'],
- ['table' => '`*PREFIX*data`', 'alias' => '`t2`']
- ], '`*PREFIX*data` `t1`, `*PREFIX*data` `t2`'],
+ [$qb->createFunction('(' . $qb->select('*')->from('test')->getSQL() . ')'), 'q', null, null, '(SELECT * FROM `*PREFIX*test`) `q`'],
+ ['data', null, null, null, '`*PREFIX*data`'],
+ ['data', 't', null, null, '`*PREFIX*data` `t`'],
+ ['data1', null, 'data2', null, '`*PREFIX*data1`, `*PREFIX*data2`'],
+ ['data', 't1', 'data', 't2', '`*PREFIX*data` `t1`, `*PREFIX*data` `t2`'],
];
}
/**
* @dataProvider dataFrom
- *
- * @param string|IQueryFunction $table1Name
- * @param string $table1Alias
- * @param string|IQueryFunction $table2Name
- * @param string $table2Alias
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testFrom($table1Name, $table1Alias, $table2Name, $table2Alias, $expectedQueryPart, $expectedQuery) {
+ public function testFrom(string|IQueryFunction $table1Name, ?string $table1Alias, null|string|IQueryFunction $table2Name, ?string $table2Alias, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->from($table1Name, $table1Alias);
if ($table2Name !== null) {
$this->queryBuilder->from($table2Name, $table2Alias);
}
$this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('from')
- );
-
- $this->assertSame(
- 'SELECT FROM ' . $expectedQuery,
+ 'SELECT * FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataJoin() {
+ public function dataJoin(): array {
return [
- [
- 'd1', 'data2', null, null,
- ['`d1`' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` '
- ],
[
'd1', 'data2', 'd2', null,
- ['`d1`' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => null]]],
'`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` `d2`'
],
[
'd1', 'data2', 'd2', '`d1`.`field1` = `d2`.`field2`',
- ['`d1`' => [['joinType' => 'inner', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => '`d1`.`field1` = `d2`.`field2`']]],
'`*PREFIX*data1` `d1` INNER JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
],
@@ -563,15 +508,9 @@ public function dataJoin() {
/**
* @dataProvider dataJoin
- *
- * @param string $fromAlias
- * @param string $tableName
- * @param string $tableAlias
- * @param string $condition
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) {
+ public function testJoin(string $fromAlias, string $tableName, string $tableAlias, ?string $condition, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->from('data1', 'd1');
$this->queryBuilder->join(
$fromAlias,
@@ -580,28 +519,18 @@ public function testJoin($fromAlias, $tableName, $tableAlias, $condition, $expec
$condition
);
- $this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('join')
- );
$this->assertSame(
- 'SELECT FROM ' . $expectedQuery,
+ 'SELECT * FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
/**
* @dataProvider dataJoin
- *
- * @param string $fromAlias
- * @param string $tableName
- * @param string $tableAlias
- * @param string $condition
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testInnerJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) {
+ public function testInnerJoin(string $fromAlias, string $tableName, string $tableAlias, ?string $condition, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->from('data1', 'd1');
$this->queryBuilder->innerJoin(
$fromAlias,
@@ -611,31 +540,19 @@ public function testInnerJoin($fromAlias, $tableName, $tableAlias, $condition, $
);
$this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('join')
- );
-
- $this->assertSame(
- 'SELECT FROM ' . $expectedQuery,
+ 'SELECT * FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataLeftJoin() {
+ public function dataLeftJoin(): array {
return [
- [
- 'd1', 'data2', null, null,
- ['`d1`' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` '
- ],
[
'd1', 'data2', 'd2', null,
- ['`d1`' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => null]]],
'`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` `d2`'
],
[
'd1', 'data2', 'd2', '`d1`.`field1` = `d2`.`field2`',
- ['`d1`' => [['joinType' => 'left', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => '`d1`.`field1` = `d2`.`field2`']]],
'`*PREFIX*data1` `d1` LEFT JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
],
];
@@ -643,15 +560,9 @@ public function dataLeftJoin() {
/**
* @dataProvider dataLeftJoin
- *
- * @param string $fromAlias
- * @param string $tableName
- * @param string $tableAlias
- * @param string $condition
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testLeftJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) {
+ public function testLeftJoin(string $fromAlias, string $tableName, string $tableAlias, ?string $condition, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->from('data1', 'd1');
$this->queryBuilder->leftJoin(
$fromAlias,
@@ -661,31 +572,19 @@ public function testLeftJoin($fromAlias, $tableName, $tableAlias, $condition, $e
);
$this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('join')
- );
-
- $this->assertSame(
- 'SELECT FROM ' . $expectedQuery,
+ 'SELECT * FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataRightJoin() {
+ public function dataRightJoin(): array {
return [
- [
- 'd1', 'data2', null, null,
- ['`d1`' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => null, 'joinCondition' => null]]],
- '`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` '
- ],
[
'd1', 'data2', 'd2', null,
- ['`d1`' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => null]]],
'`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` `d2`'
],
[
'd1', 'data2', 'd2', '`d1`.`field1` = `d2`.`field2`',
- ['`d1`' => [['joinType' => 'right', 'joinTable' => '`*PREFIX*data2`', 'joinAlias' => '`d2`', 'joinCondition' => '`d1`.`field1` = `d2`.`field2`']]],
'`*PREFIX*data1` `d1` RIGHT JOIN `*PREFIX*data2` `d2` ON `d1`.`field1` = `d2`.`field2`'
],
];
@@ -693,15 +592,9 @@ public function dataRightJoin() {
/**
* @dataProvider dataRightJoin
- *
- * @param string $fromAlias
- * @param string $tableName
- * @param string $tableAlias
- * @param string $condition
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testRightJoin($fromAlias, $tableName, $tableAlias, $condition, $expectedQueryPart, $expectedQuery) {
+ public function testRightJoin(string $fromAlias, string $tableName, string $tableAlias, ?string $condition, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->from('data1', 'd1');
$this->queryBuilder->rightJoin(
$fromAlias,
@@ -711,79 +604,53 @@ public function testRightJoin($fromAlias, $tableName, $tableAlias, $condition, $
);
$this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('join')
- );
-
- $this->assertSame(
- 'SELECT FROM ' . $expectedQuery,
+ 'SELECT * FROM ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataSet() {
+ public function dataSet(): array {
return [
- ['column1', new Literal('value'), null, null, ['`column1` = value'], '`column1` = value'],
- ['column1', new Parameter(':param'), null, null, ['`column1` = :param'], '`column1` = :param'],
- ['column1', 'column2', null, null, ['`column1` = `column2`'], '`column1` = `column2`'],
- ['column1', 'column2', 'column3', new Literal('value'), ['`column1` = `column2`', '`column3` = value'], '`column1` = `column2`, `column3` = value'],
+ ['column1', new Literal('value'), null, null, '`column1` = value'],
+ ['column1', new Parameter(':param'), null, null, '`column1` = :param'],
+ ['column1', 'column2', null, null, '`column1` = `column2`'],
+ ['column1', 'column2', 'column3', new Literal('value'), '`column1` = `column2`, `column3` = value'],
];
}
/**
* @dataProvider dataSet
- *
- * @param string $partOne1
- * @param string $partOne2
- * @param string $partTwo1
- * @param string $partTwo2
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testSet($partOne1, $partOne2, $partTwo1, $partTwo2, $expectedQueryPart, $expectedQuery) {
+ public function testSet(string $partOne1, string|Literal|Parameter $partOne2, ?string $partTwo1, null|string|Literal|Parameter $partTwo2, string $expectedQuery): void {
$this->queryBuilder->update('data');
$this->queryBuilder->set($partOne1, $partOne2);
if ($partTwo1 !== null) {
$this->queryBuilder->set($partTwo1, $partTwo2);
}
- $this->assertSame(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('set')
- );
-
$this->assertSame(
'UPDATE `*PREFIX*data` SET ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataWhere() {
+ public function dataWhere(): array {
return [
- [['where1'], new CompositeExpression('AND', ['where1']), 'where1'],
- [['where1', 'where2'], new CompositeExpression('AND', ['where1', 'where2']), '(where1) AND (where2)'],
+ [['where1'], 'where1'],
+ [['where1', 'where2'], '(where1) AND (where2)'],
];
}
/**
* @dataProvider dataWhere
- *
- * @param array $whereArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testWhere($whereArguments, $expectedQueryPart, $expectedQuery) {
+ public function testWhere(array $whereArguments, string $expectedQuery): void {
$this->queryBuilder->select('column');
call_user_func_array(
[$this->queryBuilder, 'where'],
$whereArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('where')
- );
-
$this->assertSame(
'SELECT `column` WHERE ' . $expectedQuery,
$this->queryBuilder->getSQL()
@@ -797,103 +664,75 @@ public function testWhere($whereArguments, $expectedQueryPart, $expectedQuery) {
* @param array $expectedQueryPart
* @param string $expectedQuery
*/
- public function testAndWhere($whereArguments, $expectedQueryPart, $expectedQuery) {
+ public function testAndWhere(array $whereArguments, string $expectedQuery): void {
$this->queryBuilder->select('column');
call_user_func_array(
[$this->queryBuilder, 'andWhere'],
$whereArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('where')
- );
-
$this->assertSame(
'SELECT `column` WHERE ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataOrWhere() {
+ public function dataOrWhere(): array {
return [
- [['where1'], new CompositeExpression('OR', ['where1']), 'where1'],
- [['where1', 'where2'], new CompositeExpression('OR', ['where1', 'where2']), '(where1) OR (where2)'],
+ [['where1'], 'where1'],
+ [['where1', 'where2'], '(where1) OR (where2)'],
];
}
/**
* @dataProvider dataOrWhere
- *
- * @param array $whereArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testOrWhere($whereArguments, $expectedQueryPart, $expectedQuery) {
+ public function testOrWhere(array $whereArguments, string $expectedQuery): void {
$this->queryBuilder->select('column');
call_user_func_array(
[$this->queryBuilder, 'orWhere'],
$whereArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('where')
- );
-
$this->assertSame(
'SELECT `column` WHERE ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataGroupBy() {
+ public function dataGroupBy(): array {
return [
- [['column1'], ['`column1`'], '`column1`'],
- [['column1', 'column2'], ['`column1`', '`column2`'], '`column1`, `column2`'],
+ [['column1'], '`column1`'],
+ [['column1', 'column2'], '`column1`, `column2`'],
];
}
/**
* @dataProvider dataGroupBy
- *
- * @param array $groupByArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testGroupBy($groupByArguments, $expectedQueryPart, $expectedQuery) {
+ public function testGroupBy(array $groupByArguments, string $expectedQuery): void {
$this->queryBuilder->select('column');
call_user_func_array(
[$this->queryBuilder, 'groupBy'],
$groupByArguments
);
-
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('groupBy')
- );
-
$this->assertSame(
'SELECT `column` GROUP BY ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataAddGroupBy() {
+ public function dataAddGroupBy(): array {
return [
- [['column2'], ['`column1`', '`column2`'], '`column1`, `column2`'],
- [['column2', 'column3'], ['`column1`', '`column2`', '`column3`'], '`column1`, `column2`, `column3`'],
+ [['column2'], '`column1`, `column2`'],
+ [['column2', 'column3'], '`column1`, `column2`, `column3`'],
];
}
/**
* @dataProvider dataAddGroupBy
- *
- * @param array $groupByArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testAddGroupBy($groupByArguments, $expectedQueryPart, $expectedQuery) {
+ public function testAddGroupBy(array $groupByArguments, string $expectedQuery): void {
$this->queryBuilder->select('column');
$this->queryBuilder->groupBy('column1');
call_user_func_array(
@@ -901,40 +740,25 @@ public function testAddGroupBy($groupByArguments, $expectedQueryPart, $expectedQ
$groupByArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('groupBy')
- );
-
$this->assertSame(
'SELECT `column` GROUP BY ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataSetValue() {
+ public function dataSetValue(): array {
return [
- ['column', 'value', ['`column`' => 'value'], '(`column`) VALUES(value)'],
+ ['column', 'value', '(`column`) VALUES(value)'],
];
}
/**
* @dataProvider dataSetValue
- *
- * @param string $column
- * @param string $value
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testSetValue($column, $value, $expectedQueryPart, $expectedQuery) {
+ public function testSetValue(string $column, string $value, string $expectedQuery): void {
$this->queryBuilder->insert('data');
$this->queryBuilder->setValue($column, $value);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('values')
- );
-
$this->assertSame(
'INSERT INTO `*PREFIX*data` ' . $expectedQuery,
$this->queryBuilder->getSQL()
@@ -943,41 +767,29 @@ public function testSetValue($column, $value, $expectedQueryPart, $expectedQuery
/**
* @dataProvider dataSetValue
- *
- * @param string $column
- * @param string $value
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testValues($column, $value, $expectedQueryPart, $expectedQuery) {
+ public function testValues(string $column, string $value, string $expectedQuery): void {
$this->queryBuilder->insert('data');
$this->queryBuilder->values([
$column => $value,
]);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('values')
- );
-
$this->assertSame(
'INSERT INTO `*PREFIX*data` ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataHaving() {
+ public function dataHaving(): array {
return [
- [['condition1'], new CompositeExpression('AND', ['condition1']), 'HAVING condition1'],
- [['condition1', 'condition2'], new CompositeExpression('AND', ['condition1', 'condition2']), 'HAVING (condition1) AND (condition2)'],
+ [['condition1'], 'HAVING condition1'],
+ [['condition1', 'condition2'], 'HAVING (condition1) AND (condition2)'],
[
- [new CompositeExpression('OR', ['condition1', 'condition2'])],
- new CompositeExpression('OR', ['condition1', 'condition2']),
+ [new CompositeExpression('OR', 'condition1', 'condition2')],
'HAVING (condition1) OR (condition2)'
],
[
- [new CompositeExpression('AND', ['condition1', 'condition2'])],
- new CompositeExpression('AND', ['condition1', 'condition2']),
+ [new CompositeExpression('AND', 'condition1', 'condition2')],
'HAVING (condition1) AND (condition2)'
],
];
@@ -985,40 +797,30 @@ public function dataHaving() {
/**
* @dataProvider dataHaving
- *
- * @param array $havingArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testHaving($havingArguments, $expectedQueryPart, $expectedQuery) {
+ public function testHaving(array $havingArguments, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
call_user_func_array(
[$this->queryBuilder, 'having'],
$havingArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('having')
- );
-
$this->assertSame(
- 'SELECT ' . $expectedQuery,
+ 'SELECT * ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataAndHaving() {
+ public function dataAndHaving(): array {
return [
- [['condition2'], new CompositeExpression('AND', ['condition1', 'condition2']), 'HAVING (condition1) AND (condition2)'],
- [['condition2', 'condition3'], new CompositeExpression('AND', ['condition1', 'condition2', 'condition3']), 'HAVING (condition1) AND (condition2) AND (condition3)'],
+ [['condition2'], 'HAVING (condition1) AND (condition2)'],
+ [['condition2', 'condition3'], 'HAVING (condition1) AND (condition2) AND (condition3)'],
[
- [new CompositeExpression('OR', ['condition2', 'condition3'])],
- new CompositeExpression('AND', ['condition1', new CompositeExpression('OR', ['condition2', 'condition3'])]),
+ [new CompositeExpression('OR', 'condition2', 'condition3')],
'HAVING (condition1) AND ((condition2) OR (condition3))'
],
[
- [new CompositeExpression('AND', ['condition2', 'condition3'])],
- new CompositeExpression('AND', ['condition1', new CompositeExpression('AND', ['condition2', 'condition3'])]),
+ [new CompositeExpression('AND', 'condition2', 'condition3')],
'HAVING (condition1) AND ((condition2) AND (condition3))'
],
];
@@ -1026,41 +828,31 @@ public function dataAndHaving() {
/**
* @dataProvider dataAndHaving
- *
- * @param array $havingArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testAndHaving($havingArguments, $expectedQueryPart, $expectedQuery) {
+ public function testAndHaving(array $havingArguments, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->having('condition1');
call_user_func_array(
[$this->queryBuilder, 'andHaving'],
$havingArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('having')
- );
-
$this->assertSame(
- 'SELECT ' . $expectedQuery,
+ 'SELECT * ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataOrHaving() {
+ public function dataOrHaving(): array {
return [
- [['condition2'], new CompositeExpression('OR', ['condition1', 'condition2']), 'HAVING (condition1) OR (condition2)'],
- [['condition2', 'condition3'], new CompositeExpression('OR', ['condition1', 'condition2', 'condition3']), 'HAVING (condition1) OR (condition2) OR (condition3)'],
+ [['condition2'], 'HAVING (condition1) OR (condition2)'],
+ [['condition2', 'condition3'], 'HAVING (condition1) OR (condition2) OR (condition3)'],
[
- [new CompositeExpression('OR', ['condition2', 'condition3'])],
- new CompositeExpression('OR', ['condition1', new CompositeExpression('OR', ['condition2', 'condition3'])]),
+ [new CompositeExpression('OR', 'condition2', 'condition3')],
'HAVING (condition1) OR ((condition2) OR (condition3))'
],
[
- [new CompositeExpression('AND', ['condition2', 'condition3'])],
- new CompositeExpression('OR', ['condition1', new CompositeExpression('AND', ['condition2', 'condition3'])]),
+ [new CompositeExpression('AND', 'condition2', 'condition3')],
'HAVING (condition1) OR ((condition2) AND (condition3))'
],
];
@@ -1068,93 +860,66 @@ public function dataOrHaving() {
/**
* @dataProvider dataOrHaving
- *
- * @param array $havingArguments
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testOrHaving($havingArguments, $expectedQueryPart, $expectedQuery) {
+ public function testOrHaving(array $havingArguments, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->having('condition1');
call_user_func_array(
[$this->queryBuilder, 'orHaving'],
$havingArguments
);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('having')
- );
-
$this->assertSame(
- 'SELECT ' . $expectedQuery,
+ 'SELECT * ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataOrderBy() {
+ public function dataOrderBy(): array {
return [
- ['column', null, ['`column` ASC'], 'ORDER BY `column` ASC'],
- ['column', 'ASC', ['`column` ASC'], 'ORDER BY `column` ASC'],
- ['column', 'DESC', ['`column` DESC'], 'ORDER BY `column` DESC'],
+ ['column', null, 'ORDER BY `column` ASC'],
+ ['column', 'ASC', 'ORDER BY `column` ASC'],
+ ['column', 'DESC', 'ORDER BY `column` DESC'],
];
}
/**
* @dataProvider dataOrderBy
- *
- * @param string $sort
- * @param string $order
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testOrderBy($sort, $order, $expectedQueryPart, $expectedQuery) {
+ public function testOrderBy(string $sort, ?string $order, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->orderBy($sort, $order);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('orderBy')
- );
-
$this->assertSame(
- 'SELECT ' . $expectedQuery,
+ 'SELECT * ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
- public function dataAddOrderBy() {
+ public function dataAddOrderBy(): array {
return [
- ['column2', null, null, ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'],
- ['column2', null, 'ASC', ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'],
- ['column2', null, 'DESC', ['`column1` DESC', '`column2` ASC'], 'ORDER BY `column1` DESC, `column2` ASC'],
- ['column2', 'ASC', null, ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'],
- ['column2', 'ASC', 'ASC', ['`column1` ASC', '`column2` ASC'], 'ORDER BY `column1` ASC, `column2` ASC'],
- ['column2', 'ASC', 'DESC', ['`column1` DESC', '`column2` ASC'], 'ORDER BY `column1` DESC, `column2` ASC'],
- ['column2', 'DESC', null, ['`column1` ASC', '`column2` DESC'], 'ORDER BY `column1` ASC, `column2` DESC'],
- ['column2', 'DESC', 'ASC', ['`column1` ASC', '`column2` DESC'], 'ORDER BY `column1` ASC, `column2` DESC'],
- ['column2', 'DESC', 'DESC', ['`column1` DESC', '`column2` DESC'], 'ORDER BY `column1` DESC, `column2` DESC'],
+ ['column2', null, null, 'ORDER BY `column1` ASC, `column2` ASC'],
+ ['column2', null, 'ASC', 'ORDER BY `column1` ASC, `column2` ASC'],
+ ['column2', null, 'DESC', 'ORDER BY `column1` DESC, `column2` ASC'],
+ ['column2', 'ASC', null, 'ORDER BY `column1` ASC, `column2` ASC'],
+ ['column2', 'ASC', 'ASC', 'ORDER BY `column1` ASC, `column2` ASC'],
+ ['column2', 'ASC', 'DESC', 'ORDER BY `column1` DESC, `column2` ASC'],
+ ['column2', 'DESC', null, 'ORDER BY `column1` ASC, `column2` DESC'],
+ ['column2', 'DESC', 'ASC', 'ORDER BY `column1` ASC, `column2` DESC'],
+ ['column2', 'DESC', 'DESC', 'ORDER BY `column1` DESC, `column2` DESC'],
];
}
/**
* @dataProvider dataAddOrderBy
- *
- * @param string $sort2
- * @param string $order2
- * @param string $order1
- * @param array $expectedQueryPart
- * @param string $expectedQuery
*/
- public function testAddOrderBy($sort2, $order2, $order1, $expectedQueryPart, $expectedQuery) {
+ public function testAddOrderBy(string $sort2, ?string $order2, ?string $order1, string $expectedQuery): void {
+ $this->queryBuilder->select('*');
$this->queryBuilder->orderBy('column1', $order1);
$this->queryBuilder->addOrderBy($sort2, $order2);
- $this->assertEquals(
- $expectedQueryPart,
- $this->queryBuilder->getQueryPart('orderBy')
- );
-
$this->assertSame(
- 'SELECT ' . $expectedQuery,
+ 'SELECT * ' . $expectedQuery,
$this->queryBuilder->getSQL()
);
}
@@ -1253,11 +1018,11 @@ public function testGetColumnName($column, $prefix, $expected) {
);
}
- public function testExecuteWithoutLogger() {
+ public function testExecuteWithoutLogger(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeStatement')
->willReturn(3);
$queryBuilder
->expects($this->any())
@@ -1272,11 +1037,12 @@ public function testExecuteWithoutLogger() {
->with('log_query', false)
->willReturn(false);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ $this->queryBuilder->insert('migrations');
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->assertEquals(3, $this->queryBuilder->execute());
}
- public function testExecuteWithLoggerAndNamedArray() {
+ public function testExecuteWithLoggerAndNamedArray(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$queryBuilder
->expects($this->any())
@@ -1291,7 +1057,7 @@ public function testExecuteWithLoggerAndNamedArray() {
->willReturn('SELECT * FROM FOO WHERE BAR = ?');
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeStatement')
->willReturn(3);
$this->logger
->expects($this->once())
@@ -1310,11 +1076,12 @@ public function testExecuteWithLoggerAndNamedArray() {
->with('log_query', false)
->willReturn(true);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ $this->queryBuilder->insert('migrations');
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->assertEquals(3, $this->queryBuilder->execute());
}
- public function testExecuteWithLoggerAndUnnamedArray() {
+ public function testExecuteWithLoggerAndUnnamedArray(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$queryBuilder
->expects($this->any())
@@ -1326,7 +1093,7 @@ public function testExecuteWithLoggerAndUnnamedArray() {
->willReturn('SELECT * FROM FOO WHERE BAR = ?');
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeStatement')
->willReturn(3);
$this->logger
->expects($this->once())
@@ -1345,11 +1112,12 @@ public function testExecuteWithLoggerAndUnnamedArray() {
->with('log_query', false)
->willReturn(true);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ $this->queryBuilder->insert('migrations');
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->assertEquals(3, $this->queryBuilder->execute());
}
- public function testExecuteWithLoggerAndNoParams() {
+ public function testExecuteWithLoggerAndNoParams(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$queryBuilder
->expects($this->any())
@@ -1361,7 +1129,7 @@ public function testExecuteWithLoggerAndNoParams() {
->willReturn('SELECT * FROM FOO WHERE BAR = ?');
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeStatement')
->willReturn(3);
$this->logger
->expects($this->once())
@@ -1379,11 +1147,12 @@ public function testExecuteWithLoggerAndNoParams() {
->with('log_query', false)
->willReturn(true);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ $this->queryBuilder->insert('migrations');
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->assertEquals(3, $this->queryBuilder->execute());
}
- public function testExecuteWithParameterTooLarge() {
+ public function testExecuteWithParameterTooLarge(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$p = array_fill(0, 1001, 'foo');
$queryBuilder
@@ -1396,7 +1165,7 @@ public function testExecuteWithParameterTooLarge() {
->willReturn('SELECT * FROM FOO WHERE BAR IN (?)');
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeQuery')
->willReturn($this->createMock(Result::class));
$this->logger
->expects($this->once())
@@ -1414,11 +1183,11 @@ public function testExecuteWithParameterTooLarge() {
->with('log_query', false)
->willReturn(false);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->queryBuilder->execute();
}
- public function testExecuteWithParametersTooMany() {
+ public function testExecuteWithParametersTooMany(): void {
$queryBuilder = $this->createMock(\Doctrine\DBAL\Query\QueryBuilder::class);
$p = array_fill(0, 999, 'foo');
$queryBuilder
@@ -1431,7 +1200,7 @@ public function testExecuteWithParametersTooMany() {
->willReturn('SELECT * FROM FOO WHERE BAR IN (?) OR BAR IN (?)');
$queryBuilder
->expects($this->once())
- ->method('execute')
+ ->method('executeQuery')
->willReturn($this->createMock(Result::class));
$this->logger
->expects($this->once())
@@ -1449,7 +1218,7 @@ public function testExecuteWithParametersTooMany() {
->with('log_query', false)
->willReturn(false);
- $this->invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
+ self::invokePrivate($this->queryBuilder, 'queryBuilder', [$queryBuilder]);
$this->queryBuilder->execute();
}
}
diff --git a/tests/lib/Files/Cache/CacheTest.php b/tests/lib/Files/Cache/CacheTest.php
index faecbf54491c0..a36607eb9659e 100644
--- a/tests/lib/Files/Cache/CacheTest.php
+++ b/tests/lib/Files/Cache/CacheTest.php
@@ -7,12 +7,12 @@
namespace Test\Files\Cache;
-use Doctrine\DBAL\Platforms\MySqlPlatform;
use OC\Files\Cache\Cache;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchQuery;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Search\ISearchComparison;
+use OCP\IDBConnection;
use OCP\IUser;
class LongId extends \OC\Files\Storage\Temporary {
@@ -142,7 +142,7 @@ public function testFolder($folder) {
if (strpos($folder, 'F09F9890')) {
// 4 byte UTF doesn't work on mysql
$params = \OC::$server->get(\OC\DB\Connection::class)->getParams();
- if (\OC::$server->getDatabaseConnection()->getDatabasePlatform() instanceof MySqlPlatform && $params['charset'] !== 'utf8mb4') {
+ if (\OC::$server->getDatabaseConnection()->getDatabaseProvider() === IDBConnection::PLATFORM_MYSQL && $params['charset'] !== 'utf8mb4') {
$this->markTestSkipped('MySQL doesn\'t support 4 byte UTF-8');
}
}
diff --git a/tests/lib/Repair/RepairCollationTest.php b/tests/lib/Repair/RepairCollationTest.php
index 55bda8337c978..6d3946b2a85b8 100644
--- a/tests/lib/Repair/RepairCollationTest.php
+++ b/tests/lib/Repair/RepairCollationTest.php
@@ -7,7 +7,6 @@
namespace Test\Repair;
-use Doctrine\DBAL\Platforms\MySqlPlatform;
use OC\Repair\Collation;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
@@ -61,7 +60,7 @@ protected function setUp(): void {
$this->connection = \OC::$server->get(IDBConnection::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->config = \OC::$server->getConfig();
- if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) {
+ if ($this->connection->getDatabaseProvider() !== IDBConnection::PLATFORM_MYSQL) {
$this->markTestSkipped("Test only relevant on MySql");
}
@@ -73,7 +72,7 @@ protected function setUp(): void {
}
protected function tearDown(): void {
- $this->connection->getInner()->getSchemaManager()->dropTable($this->tableName);
+ $this->connection->getInner()->createSchemaManager()->dropTable($this->tableName);
parent::tearDown();
}