Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>tags/v21.0.0beta5
@@ -1 +1 @@ | |||
Subproject commit 86573beb84cf3b62b6d01ee377225df83b7d2453 | |||
Subproject commit 09596e43fba86a3643879595a8fb6fece4af6a78 |
@@ -82,7 +82,7 @@ class CardSearchDao { | |||
->setMaxResults(1); | |||
$result = $cardQuery->execute(); | |||
/** @var string|resource|false $card */ | |||
$card = $result->fetchColumn(0); | |||
$card = $result->fetchOne(); | |||
if ($card === false) { | |||
return null; |
@@ -401,7 +401,7 @@ class UpdateCalendarResourcesRoomsBackgroundJob extends TimedJob { | |||
return array_map(function ($row) { | |||
return $row['resource_id']; | |||
}, $stmt->fetchAll(\PDO::FETCH_NAMED)); | |||
}, $stmt->fetchAll()); | |||
} | |||
/** | |||
@@ -435,6 +435,6 @@ class UpdateCalendarResourcesRoomsBackgroundJob extends TimedJob { | |||
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resourceId))); | |||
$stmt = $query->execute(); | |||
return $stmt->fetch(\PDO::FETCH_NAMED)['id']; | |||
return $stmt->fetch()['id']; | |||
} | |||
} |
@@ -256,7 +256,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
} | |||
$result = $query->execute(); | |||
$column = (int)$result->fetchColumn(); | |||
$column = (int)$result->fetchOne(); | |||
$result->closeCursor(); | |||
return $column; | |||
} | |||
@@ -1114,7 +1114,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
->andWhere($q->expr()->eq('calendartype', $q->createNamedParameter($calendarType))); | |||
$result = $q->execute(); | |||
$count = (int) $result->fetchColumn(); | |||
$count = (int) $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count !== 0) { | |||
@@ -1963,7 +1963,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
// Current synctoken | |||
$stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*calendars` WHERE `id` = ?'); | |||
$stmt->execute([ $calendarId ]); | |||
$currentToken = $stmt->fetchColumn(0); | |||
$currentToken = $stmt->fetchOne(); | |||
if (is_null($currentToken)) { | |||
return null; | |||
@@ -2373,7 +2373,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
->from($table) | |||
->where($query->expr()->eq('id', $query->createNamedParameter($calendarId))); | |||
$result = $query->execute(); | |||
$syncToken = (int)$result->fetchColumn(); | |||
$syncToken = (int)$result->fetchOne(); | |||
$result->closeCursor(); | |||
$query = $this->db->getQueryBuilder(); |
@@ -140,7 +140,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
->where($query->expr()->eq('principaluri', $query->createNamedParameter($principalUri))); | |||
$result = $query->execute(); | |||
$column = (int) $result->fetchColumn(); | |||
$column = (int) $result->fetchOne(); | |||
$result->closeCursor(); | |||
return $column; | |||
} | |||
@@ -661,7 +661,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
->andWhere($q->expr()->eq('uid', $q->createNamedParameter($uid))) | |||
->setMaxResults(1); | |||
$result = $q->execute(); | |||
$count = (bool)$result->fetchColumn(); | |||
$count = (bool)$result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count) { | |||
throw new \Sabre\DAV\Exception\BadRequest('VCard object with uid already exists in this addressbook collection.'); | |||
@@ -864,7 +864,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { | |||
// Current synctoken | |||
$stmt = $this->db->prepare('SELECT `synctoken` FROM `*PREFIX*addressbooks` WHERE `id` = ?'); | |||
$stmt->execute([$addressBookId]); | |||
$currentToken = $stmt->fetchColumn(0); | |||
$currentToken = $stmt->fetchOne(); | |||
if (is_null($currentToken)) { | |||
return null; |
@@ -77,7 +77,7 @@ class BuildCalendarSearchIndex implements IRepairStep { | |||
$query->select($query->createFunction('MAX(' . $query->getColumnName('id') . ')')) | |||
->from('calendarobjects'); | |||
$result = $query->execute(); | |||
$maxId = (int) $result->fetchColumn(); | |||
$maxId = (int) $result->fetchOne(); | |||
$result->closeCursor(); | |||
$output->info('Add background job'); |
@@ -74,8 +74,8 @@ class BuildSocialSearchIndex implements IRepairStep { | |||
$query->select($query->func()->max('cardid')) | |||
->from('cards_properties') | |||
->where($query->expr()->eq('name', $query->createNamedParameter('X-SOCIALPROFILE'))); | |||
$maxId = (int)$query->execute()->fetchColumn(); | |||
$maxId = (int)$query->execute()->fetchOne(); | |||
if ($maxId === 0) { | |||
return; | |||
} |
@@ -107,7 +107,7 @@ class CalDAVRemoveEmptyValue implements IRepairStep { | |||
$query->select($query->func()->count('*', 'num_entries')) | |||
->from('calendarobjects'); | |||
$result = $query->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$numChunks = ceil($count / $chunkSize); |
@@ -88,7 +88,7 @@ class RegisterBuildReminderIndexBackgroundJob implements IRepairStep { | |||
$query->select($query->createFunction('MAX(' . $query->getColumnName('id') . ')')) | |||
->from('calendarobjects'); | |||
$result = $query->execute(); | |||
$maxId = (int) $result->fetchColumn(); | |||
$maxId = (int) $result->fetchOne(); | |||
$result->closeCursor(); | |||
$output->info('Add background job'); |
@@ -106,7 +106,7 @@ class CleanupRemoteStorages extends Command { | |||
IQueryBuilder::PARAM_STR) | |||
); | |||
$result = $queryBuilder->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$output->writeln("$count files can be deleted for storage $numericId"); | |||
} | |||
@@ -33,6 +33,7 @@ | |||
namespace OCA\Files_Sharing\External; | |||
use Doctrine\DBAL\Driver\Exception; | |||
use OC\Files\Filesystem; | |||
use OCA\FederatedFileSharing\Events\FederatedShareAddedEvent; | |||
use OCA\Files_Sharing\Helper; | |||
@@ -129,7 +130,7 @@ class Manager { | |||
* @param string $remoteId | |||
* @param int $parent | |||
* @return Mount|null | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
*/ | |||
public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted = false, $user = null, $remoteId = '', $parent = -1) { | |||
$user = $user ? $user : $this->uid; | |||
@@ -199,15 +200,17 @@ class Manager { | |||
* @param $remoteId | |||
* @param $parent | |||
* @param $shareType | |||
* @return bool | |||
* | |||
* @return void | |||
* @throws \Doctrine\DBAL\Driver\Exception | |||
*/ | |||
private function writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType) { | |||
private function writeShareToDb($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType): void { | |||
$query = $this->connection->prepare(' | |||
INSERT INTO `*PREFIX*share_external` | |||
(`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`, `parent`, `share_type`) | |||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) | |||
'); | |||
return $query->execute([$remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType]); | |||
$query->execute([$remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType]); | |||
} | |||
/** | |||
@@ -222,9 +225,8 @@ class Manager { | |||
FROM `*PREFIX*share_external` | |||
WHERE `id` = ?'); | |||
$result = $getShare->execute([$id]); | |||
$share = $result ? $getShare->fetch() : []; | |||
$share = $result->fetch(); | |||
$result->closeCursor(); | |||
$validShare = is_array($share) && isset($share['share_type']) && isset($share['user']); | |||
// check if the user is allowed to access it | |||
@@ -267,19 +269,24 @@ class Manager { | |||
WHERE `id` = ? AND `user` = ?'); | |||
$userShareAccepted = $acceptShare->execute([1, $mountPoint, $hash, $id, $this->uid]); | |||
} else { | |||
$result = $this->writeShareToDb( | |||
$share['remote'], | |||
$share['share_token'], | |||
$share['password'], | |||
$share['name'], | |||
$share['owner'], | |||
$this->uid, | |||
$mountPoint, $hash, 1, | |||
$share['remote_id'], | |||
$id, | |||
$share['share_type']); | |||
try { | |||
$this->writeShareToDb( | |||
$share['remote'], | |||
$share['share_token'], | |||
$share['password'], | |||
$share['name'], | |||
$share['owner'], | |||
$this->uid, | |||
$mountPoint, $hash, 1, | |||
$share['remote_id'], | |||
$id, | |||
$share['share_type']); | |||
$result = true; | |||
} catch (Exception $e) { | |||
$result = false; | |||
} | |||
} | |||
if ($userShareAccepted === true) { | |||
if ($userShareAccepted !== false) { | |||
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept'); | |||
$event = new FederatedShareAddedEvent($share['remote']); | |||
$this->eventDispatcher->dispatchTyped($event); | |||
@@ -312,19 +319,24 @@ class Manager { | |||
$this->processNotification($id); | |||
$result = true; | |||
} elseif ($share && (int)$share['share_type'] === IShare::TYPE_GROUP) { | |||
$result = $this->writeShareToDb( | |||
$share['remote'], | |||
$share['share_token'], | |||
$share['password'], | |||
$share['name'], | |||
$share['owner'], | |||
$this->uid, | |||
$share['mountpoint'], | |||
$share['mountpoint_hash'], | |||
0, | |||
$share['remote_id'], | |||
$id, | |||
$share['share_type']); | |||
try { | |||
$this->writeShareToDb( | |||
$share['remote'], | |||
$share['share_token'], | |||
$share['password'], | |||
$share['name'], | |||
$share['owner'], | |||
$this->uid, | |||
$share['mountpoint'], | |||
$share['mountpoint_hash'], | |||
0, | |||
$share['remote_id'], | |||
$id, | |||
$share['share_type']); | |||
$result = true; | |||
} catch (Exception $e) { | |||
$result = false; | |||
} | |||
$this->processNotification($id); | |||
} | |||
@@ -484,47 +496,50 @@ class Manager { | |||
return $result; | |||
} | |||
public function removeShare($mountPoint) { | |||
public function removeShare($mountPoint): bool { | |||
$mountPointObj = $this->mountManager->find($mountPoint); | |||
$id = $mountPointObj->getStorage()->getCache()->getId(''); | |||
$mountPoint = $this->stripPath($mountPoint); | |||
$hash = md5($mountPoint); | |||
$getShare = $this->connection->prepare(' | |||
SELECT `remote`, `share_token`, `remote_id`, `share_type`, `id` | |||
FROM `*PREFIX*share_external` | |||
WHERE `mountpoint_hash` = ? AND `user` = ?'); | |||
$result = $getShare->execute([$hash, $this->uid]); | |||
$share = $getShare->fetch(); | |||
$getShare->closeCursor(); | |||
if ($result && $share !== false && (int)$share['share_type'] === IShare::TYPE_USER) { | |||
try { | |||
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); | |||
} catch (\Throwable $e) { | |||
// if we fail to notify the remote (probably cause the remote is down) | |||
// we still want the share to be gone to prevent undeletable remotes | |||
try { | |||
$getShare = $this->connection->prepare(' | |||
SELECT `remote`, `share_token`, `remote_id`, `share_type`, `id` | |||
FROM `*PREFIX*share_external` | |||
WHERE `mountpoint_hash` = ? AND `user` = ?'); | |||
$result = $getShare->execute([$hash, $this->uid]); | |||
$share = $result->fetch(); | |||
$result->closeCursor(); | |||
if ($share !== false && (int)$share['share_type'] === IShare::TYPE_USER) { | |||
try { | |||
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); | |||
} catch (\Throwable $e) { | |||
// if we fail to notify the remote (probably cause the remote is down) | |||
// we still want the share to be gone to prevent undeletable remotes | |||
} | |||
$query = $this->connection->prepare(' | |||
DELETE FROM `*PREFIX*share_external` | |||
WHERE `id` = ? | |||
'); | |||
$deleteResult = $query->execute([(int)$share['id']]); | |||
$deleteResult->closeCursor(); | |||
} elseif ($share !== false && (int)$share['share_type'] === IShare::TYPE_GROUP) { | |||
$query = $this->connection->prepare(' | |||
UPDATE `*PREFIX*share_external` | |||
SET `accepted` = ? | |||
WHERE `id` = ?'); | |||
$updateResult = $query->execute([0, (int)$share['id']]); | |||
$updateResult->closeCursor(); | |||
} | |||
$query = $this->connection->prepare(' | |||
DELETE FROM `*PREFIX*share_external` | |||
WHERE `id` = ? | |||
'); | |||
$result = (bool)$query->execute([(int)$share['id']]); | |||
} elseif ($result && $share !== false && (int)$share['share_type'] === IShare::TYPE_GROUP) { | |||
$query = $this->connection->prepare(' | |||
UPDATE `*PREFIX*share_external` | |||
SET `accepted` = ? | |||
WHERE `id` = ?'); | |||
$result = (bool)$query->execute([0, (int)$share['id']]); | |||
} | |||
if ($result) { | |||
$this->removeReShares($id); | |||
} catch (\Doctrine\DBAL\Exception $ex) { | |||
return false; | |||
} | |||
return $result; | |||
return true; | |||
} | |||
/** | |||
@@ -554,27 +569,31 @@ class Manager { | |||
* remove all shares for user $uid if the user was deleted | |||
* | |||
* @param string $uid | |||
* @return bool | |||
*/ | |||
public function removeUserShares($uid) { | |||
$getShare = $this->connection->prepare(' | |||
SELECT `remote`, `share_token`, `remote_id` | |||
FROM `*PREFIX*share_external` | |||
WHERE `user` = ?'); | |||
$result = $getShare->execute([$uid]); | |||
if ($result) { | |||
$shares = $getShare->fetchAll(); | |||
public function removeUserShares($uid): bool { | |||
try { | |||
$getShare = $this->connection->prepare(' | |||
SELECT `remote`, `share_token`, `remote_id` | |||
FROM `*PREFIX*share_external` | |||
WHERE `user` = ?'); | |||
$result = $getShare->execute([$uid]); | |||
$shares = $result->fetchAll(); | |||
$result->closeCursor(); | |||
foreach ($shares as $share) { | |||
$this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'decline'); | |||
} | |||
$query = $this->connection->prepare(' | |||
DELETE FROM `*PREFIX*share_external` | |||
WHERE `user` = ? | |||
'); | |||
$deleteResult = $query->execute([$uid]); | |||
$deleteResult->closeCursor(); | |||
} catch (\Doctrine\DBAL\Exception $ex) { | |||
return false; | |||
} | |||
$query = $this->connection->prepare(' | |||
DELETE FROM `*PREFIX*share_external` | |||
WHERE `user` = ? | |||
'); | |||
return (bool)$query->execute([$uid]); | |||
return true; | |||
} | |||
/** | |||
@@ -621,9 +640,14 @@ class Manager { | |||
} | |||
$query .= ' ORDER BY `id` ASC'; | |||
$shares = $this->connection->prepare($query); | |||
$result = $shares->execute($parameters); | |||
return $result ? $shares->fetchAll() : []; | |||
$sharesQuery = $this->connection->prepare($query); | |||
try { | |||
$result = $sharesQuery->execute($parameters); | |||
$shares = $result->fetchAll(); | |||
$result->closeCursor(); | |||
return $shares; | |||
} catch (\Doctrine\DBAL\Exception $e) { | |||
return []; | |||
} | |||
} | |||
} |
@@ -30,6 +30,7 @@ namespace OCA\Files_Trashbin\Tests\Command; | |||
use OC\User\Manager; | |||
use OCA\Files_Trashbin\Command\CleanUp; | |||
use OCP\Files\IRootFolder; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Exception\InvalidOptionException; | |||
use Symfony\Component\Console\Input\InputInterface; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
@@ -53,7 +54,7 @@ class CleanUpTest extends TestCase { | |||
/** @var \PHPUnit\Framework\MockObject\MockObject | IRootFolder */ | |||
protected $rootFolder; | |||
/** @var \OC\DB\Connection */ | |||
/** @var IDBConnection */ | |||
protected $dbConnection; | |||
/** @var string */ |
@@ -44,8 +44,9 @@ namespace OCA\Settings\Controller; | |||
use bantu\IniGetWrapper\IniGetWrapper; | |||
use DirectoryIterator; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Platforms\SqlitePlatform; | |||
use Doctrine\DBAL\TransactionIsolationLevel; | |||
use Doctrine\DBAL\Types\Types; | |||
use GuzzleHttp\Exception\ClientException; | |||
use OC; | |||
@@ -94,7 +95,7 @@ class CheckSetupController extends Controller { | |||
private $logger; | |||
/** @var EventDispatcherInterface */ | |||
private $dispatcher; | |||
/** @var IDBConnection|Connection */ | |||
/** @var Connection */ | |||
private $db; | |||
/** @var ILockingProvider */ | |||
private $lockingProvider; | |||
@@ -116,7 +117,7 @@ class CheckSetupController extends Controller { | |||
Checker $checker, | |||
ILogger $logger, | |||
EventDispatcherInterface $dispatcher, | |||
IDBConnection $db, | |||
Connection $db, | |||
ILockingProvider $lockingProvider, | |||
IDateTimeFormatter $dateTimeFormatter, | |||
MemoryInfo $memoryInfo, | |||
@@ -492,8 +493,8 @@ Raw output | |||
return true; | |||
} | |||
return $this->db->getTransactionIsolation() === Connection::TRANSACTION_READ_COMMITTED; | |||
} catch (DBALException $e) { | |||
return $this->db->getTransactionIsolation() === TransactionIsolationLevel::READ_COMMITTED; | |||
} catch (Exception $e) { | |||
// ignore | |||
} | |||
@@ -27,7 +27,9 @@ | |||
namespace OCA\User_LDAP\Mapping; | |||
use Doctrine\DBAL\Exception; | |||
use OC\DB\QueryBuilder\QueryBuilder; | |||
use OCP\DB\IPreparedStatement; | |||
/** | |||
* Class AbstractMapping | |||
@@ -95,24 +97,32 @@ abstract class AbstractMapping { | |||
WHERE `' . $compareCol . '` = ? | |||
'); | |||
$res = $query->execute([$search]); | |||
if ($res !== false) { | |||
return $query->fetchColumn(); | |||
try { | |||
$res = $query->execute([$search]); | |||
$data = $res->fetchOne(); | |||
$res->closeCursor(); | |||
return $data; | |||
} catch (Exception $e) { | |||
return false; | |||
} | |||
return false; | |||
} | |||
/** | |||
* Performs a DELETE or UPDATE query to the database. | |||
* | |||
* @param \Doctrine\DBAL\Driver\Statement $query | |||
* @param IPreparedStatement $statement | |||
* @param array $parameters | |||
* @return bool true if at least one row was modified, false otherwise | |||
*/ | |||
protected function modify($query, $parameters) { | |||
$result = $query->execute($parameters); | |||
return ($result === true && $query->rowCount() > 0); | |||
protected function modify(IPreparedStatement $statement, $parameters) { | |||
try { | |||
$result = $statement->execute($parameters); | |||
$updated = $result->rowCount() > 0; | |||
$result->closeCursor(); | |||
return $updated; | |||
} catch (Exception $e) { | |||
return false; | |||
} | |||
} | |||
/** | |||
@@ -139,13 +149,13 @@ abstract class AbstractMapping { | |||
*/ | |||
public function setDNbyUUID($fdn, $uuid) { | |||
$oldDn = $this->getDnByUUID($uuid); | |||
$query = $this->dbc->prepare(' | |||
$statement = $this->dbc->prepare(' | |||
UPDATE `' . $this->getTableName() . '` | |||
SET `ldap_dn` = ? | |||
WHERE `directory_uuid` = ? | |||
'); | |||
$r = $this->modify($query, [$fdn, $uuid]); | |||
$r = $this->modify($statement, [$fdn, $uuid]); | |||
if ($r && is_string($oldDn) && isset($this->cache[$oldDn])) { | |||
$this->cache[$fdn] = $this->cache[$oldDn]; | |||
@@ -165,7 +175,7 @@ abstract class AbstractMapping { | |||
* @return bool | |||
*/ | |||
public function setUUIDbyDN($uuid, $fdn) { | |||
$query = $this->dbc->prepare(' | |||
$statement = $this->dbc->prepare(' | |||
UPDATE `' . $this->getTableName() . '` | |||
SET `directory_uuid` = ? | |||
WHERE `ldap_dn` = ? | |||
@@ -173,7 +183,7 @@ abstract class AbstractMapping { | |||
unset($this->cache[$fdn]); | |||
return $this->modify($query, [$uuid, $fdn]); | |||
return $this->modify($statement, [$uuid, $fdn]); | |||
} | |||
/** | |||
@@ -215,18 +225,20 @@ abstract class AbstractMapping { | |||
* @return string[] | |||
*/ | |||
public function getNamesBySearch($search, $prefixMatch = "", $postfixMatch = "") { | |||
$query = $this->dbc->prepare(' | |||
$statement = $this->dbc->prepare(' | |||
SELECT `owncloud_name` | |||
FROM `' . $this->getTableName() . '` | |||
WHERE `owncloud_name` LIKE ? | |||
'); | |||
$res = $query->execute([$prefixMatch . $this->dbc->escapeLikeParameter($search) . $postfixMatch]); | |||
try { | |||
$res = $statement->execute([$prefixMatch . $this->dbc->escapeLikeParameter($search) . $postfixMatch]); | |||
} catch (Exception $e) { | |||
return []; | |||
} | |||
$names = []; | |||
if ($res !== false) { | |||
while ($row = $query->fetch()) { | |||
$names[] = $row['owncloud_name']; | |||
} | |||
while ($row = $res->fetch()) { | |||
$names[] = $row['owncloud_name']; | |||
} | |||
return $names; | |||
} | |||
@@ -323,15 +335,15 @@ abstract class AbstractMapping { | |||
* @return bool | |||
*/ | |||
public function unmap($name) { | |||
$query = $this->dbc->prepare(' | |||
$statement = $this->dbc->prepare(' | |||
DELETE FROM `' . $this->getTableName() . '` | |||
WHERE `owncloud_name` = ?'); | |||
return $this->modify($query, [$name]); | |||
return $this->modify($statement, [$name]); | |||
} | |||
/** | |||
* Truncate's the mapping table | |||
* Truncates the mapping table | |||
* | |||
* @return bool | |||
*/ | |||
@@ -339,7 +351,13 @@ abstract class AbstractMapping { | |||
$sql = $this->dbc | |||
->getDatabasePlatform() | |||
->getTruncateTableSQL('`' . $this->getTableName() . '`'); | |||
return $this->dbc->prepare($sql)->execute(); | |||
try { | |||
$this->dbc->executeQuery($sql); | |||
return true; | |||
} catch (Exception $e) { | |||
return false; | |||
} | |||
} | |||
/** | |||
@@ -357,7 +375,7 @@ abstract class AbstractMapping { | |||
->from($this->getTableName()); | |||
$cursor = $picker->execute(); | |||
$result = true; | |||
while ($id = $cursor->fetchColumn(0)) { | |||
while ($id = $cursor->fetchOne()) { | |||
$preCallback($id); | |||
if ($isUnmapped = $this->unmap($id)) { | |||
$postCallback($id); | |||
@@ -378,7 +396,7 @@ abstract class AbstractMapping { | |||
$query = $qb->select($qb->func()->count('ldap_dn')) | |||
->from($this->getTableName()); | |||
$res = $query->execute(); | |||
$count = $res->fetchColumn(); | |||
$count = $res->fetchOne(); | |||
$res->closeCursor(); | |||
return (int)$count; | |||
} |
@@ -25,7 +25,7 @@ declare(strict_types=1); | |||
namespace OCA\WorkflowEngine\Controller; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use OCA\WorkflowEngine\Helper\ScopeContext; | |||
use OCA\WorkflowEngine\Manager; | |||
use OCP\AppFramework\Http\DataResponse; | |||
@@ -112,7 +112,7 @@ abstract class AWorkflowController extends OCSController { | |||
throw new OCSBadRequestException($e->getMessage(), $e); | |||
} catch (\DomainException $e) { | |||
throw new OCSForbiddenException($e->getMessage(), $e); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
throw new OCSException('An internal error occurred', $e->getCode(), $e); | |||
} | |||
} | |||
@@ -139,7 +139,7 @@ abstract class AWorkflowController extends OCSController { | |||
throw new OCSBadRequestException($e->getMessage(), $e); | |||
} catch (\DomainException $e) { | |||
throw new OCSForbiddenException($e->getMessage(), $e); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
throw new OCSException('An internal error occurred', $e->getCode(), $e); | |||
} | |||
} | |||
@@ -157,7 +157,7 @@ abstract class AWorkflowController extends OCSController { | |||
throw new OCSBadRequestException($e->getMessage(), $e); | |||
} catch (\DomainException $e) { | |||
throw new OCSForbiddenException($e->getMessage(), $e); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
throw new OCSException('An internal error occurred', $e->getCode(), $e); | |||
} | |||
} |
@@ -21,7 +21,7 @@ | |||
namespace OCA\WorkflowEngine; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use OC\Cache\CappedMemoryCache; | |||
use OCA\WorkflowEngine\AppInfo\Application; | |||
use OCA\WorkflowEngine\Check\FileMimeType; | |||
@@ -290,7 +290,7 @@ class Manager implements IManager { | |||
* @param string $operation | |||
* @return array The added operation | |||
* @throws \UnexpectedValueException | |||
* @throws DBALException | |||
* @throw Exception | |||
*/ | |||
public function addOperation( | |||
string $class, | |||
@@ -315,7 +315,7 @@ class Manager implements IManager { | |||
$this->addScope($id, $scope); | |||
$this->connection->commit(); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
$this->connection->rollBack(); | |||
throw $e; | |||
} | |||
@@ -342,7 +342,7 @@ class Manager implements IManager { | |||
$result = $qb->execute(); | |||
$this->operationsByScope[$scopeContext->getHash()] = []; | |||
while ($opId = $result->fetchColumn(0)) { | |||
while ($opId = $result->fetchOne()) { | |||
$this->operationsByScope[$scopeContext->getHash()][] = (int)$opId; | |||
} | |||
$result->closeCursor(); | |||
@@ -358,7 +358,7 @@ class Manager implements IManager { | |||
* @return array The updated operation | |||
* @throws \UnexpectedValueException | |||
* @throws \DomainException | |||
* @throws DBALException | |||
* @throws Exception | |||
*/ | |||
public function updateOperation( | |||
int $id, | |||
@@ -392,7 +392,7 @@ class Manager implements IManager { | |||
->where($query->expr()->eq('id', $query->createNamedParameter($id))); | |||
$query->execute(); | |||
$this->connection->commit(); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
$this->connection->rollBack(); | |||
throw $e; | |||
} | |||
@@ -405,7 +405,7 @@ class Manager implements IManager { | |||
* @param int $id | |||
* @return bool | |||
* @throws \UnexpectedValueException | |||
* @throws DBALException | |||
* @throws Exception | |||
* @throws \DomainException | |||
*/ | |||
public function deleteOperation($id, ScopeContext $scopeContext) { | |||
@@ -425,7 +425,7 @@ class Manager implements IManager { | |||
->execute(); | |||
} | |||
$this->connection->commit(); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
$this->connection->rollBack(); | |||
throw $e; | |||
} |
@@ -25,7 +25,7 @@ declare(strict_types=1); | |||
namespace OCA\WorkflowEngine\Migration; | |||
use Doctrine\DBAL\Driver\Statement; | |||
use OCP\DB\IResult; | |||
use OCP\IDBConnection; | |||
use OCP\Migration\IOutput; | |||
use OCP\Migration\IRepairStep; | |||
@@ -52,17 +52,17 @@ class PopulateNewlyIntroducedDatabaseFields implements IRepairStep { | |||
$result->closeCursor(); | |||
} | |||
protected function populateScopeTable(Statement $ids): void { | |||
protected function populateScopeTable(IResult $ids): void { | |||
$qb = $this->dbc->getQueryBuilder(); | |||
$insertQuery = $qb->insert('flow_operations_scope'); | |||
while ($id = $ids->fetchColumn(0)) { | |||
while ($id = $ids->fetchOne()) { | |||
$insertQuery->values(['operation_id' => $qb->createNamedParameter($id), 'type' => IManager::SCOPE_ADMIN]); | |||
$insertQuery->execute(); | |||
} | |||
} | |||
protected function getIdsWithoutScope(): Statement { | |||
protected function getIdsWithoutScope(): IResult { | |||
$qb = $this->dbc->getQueryBuilder(); | |||
$selectQuery = $qb->select('o.id') | |||
->from('flow_operations', 'o') | |||
@@ -71,6 +71,8 @@ class PopulateNewlyIntroducedDatabaseFields implements IRepairStep { | |||
// The left join operation is not necessary, usually, but it's a safe-guard | |||
// in case the repair step is executed multiple times for whatever reason. | |||
return $selectQuery->execute(); | |||
/** @var IResult $result */ | |||
$result = $selectQuery->execute(); | |||
return $result; | |||
} | |||
} |
@@ -3061,10 +3061,14 @@ | |||
</MoreSpecificImplementedParamType> | |||
</file> | |||
<file src="lib/private/Archive/TAR.php"> | |||
<InvalidReturnStatement occurrences="1"> | |||
<FalsableReturnStatement occurrences="1"> | |||
<code>false</code> | |||
</FalsableReturnStatement> | |||
<InvalidReturnStatement occurrences="2"> | |||
<code>$this->tar->extractInString($path)</code> | |||
</InvalidReturnStatement> | |||
<InvalidReturnType occurrences="1"> | |||
<InvalidReturnType occurrences="2"> | |||
<code>resource</code> | |||
<code>string</code> | |||
</InvalidReturnType> | |||
<UndefinedDocblockClass occurrences="1"> | |||
@@ -3076,6 +3080,10 @@ | |||
<code>boolean|null</code> | |||
<code>boolean|null</code> | |||
</ImplementedReturnTypeMismatch> | |||
<InvalidReturnStatement occurrences="1"/> | |||
<InvalidReturnType occurrences="1"> | |||
<code>resource</code> | |||
</InvalidReturnType> | |||
</file> | |||
<file src="lib/private/Authentication/LoginCredentials/Store.php"> | |||
<RedundantCondition occurrences="1"> | |||
@@ -3584,6 +3592,9 @@ | |||
<ImplementedParamTypeMismatch occurrences="1"> | |||
<code>$eventName</code> | |||
</ImplementedParamTypeMismatch> | |||
<ImplementedReturnTypeMismatch occurrences="1"> | |||
<code>void</code> | |||
</ImplementedReturnTypeMismatch> | |||
<InvalidArgument occurrences="1"> | |||
<code>$eventName</code> | |||
</InvalidArgument> |
@@ -41,6 +41,7 @@ use OC\Authentication\Listeners\UserDeletedStoreCleanupListener; | |||
use OC\Authentication\Listeners\UserDeletedTokenCleanupListener; | |||
use OC\Authentication\Notifications\Notifier as AuthenticationNotifier; | |||
use OC\Core\Notification\CoreNotifier; | |||
use OC\DB\Connection; | |||
use OC\DB\MissingColumnInformation; | |||
use OC\DB\MissingIndexInformation; | |||
use OC\DB\MissingPrimaryKeyInformation; | |||
@@ -82,7 +83,7 @@ class Application extends App { | |||
/** @var MissingIndexInformation $subject */ | |||
$subject = $event->getSubject(); | |||
$schema = new SchemaWrapper($container->query(IDBConnection::class)); | |||
$schema = new SchemaWrapper($container->query(Connection::class)); | |||
if ($schema->hasTable('share')) { | |||
$table = $schema->getTable('share'); | |||
@@ -192,7 +193,7 @@ class Application extends App { | |||
/** @var MissingPrimaryKeyInformation $subject */ | |||
$subject = $event->getSubject(); | |||
$schema = new SchemaWrapper($container->query(IDBConnection::class)); | |||
$schema = new SchemaWrapper($container->query(Connection::class)); | |||
if ($schema->hasTable('federated_reshares')) { | |||
$table = $schema->getTable('federated_reshares'); | |||
@@ -249,7 +250,7 @@ class Application extends App { | |||
/** @var MissingColumnInformation $subject */ | |||
$subject = $event->getSubject(); | |||
$schema = new SchemaWrapper($container->query(IDBConnection::class)); | |||
$schema = new SchemaWrapper($container->query(Connection::class)); | |||
if ($schema->hasTable('comments')) { | |||
$table = $schema->getTable('comments'); |
@@ -26,6 +26,7 @@ declare(strict_types=1); | |||
namespace OC\Core\Command\Db; | |||
use OC\DB\Connection; | |||
use OC\DB\SchemaWrapper; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -44,13 +45,13 @@ use Symfony\Component\EventDispatcher\GenericEvent; | |||
*/ | |||
class AddMissingColumns extends Command { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** @var EventDispatcherInterface */ | |||
private $dispatcher; | |||
public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) { | |||
public function __construct(Connection $connection, EventDispatcherInterface $dispatcher) { | |||
parent::__construct(); | |||
$this->connection = $connection; |
@@ -33,6 +33,7 @@ declare(strict_types=1); | |||
namespace OC\Core\Command\Db; | |||
use OC\DB\Connection; | |||
use OC\DB\SchemaWrapper; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -51,13 +52,13 @@ use Symfony\Component\EventDispatcher\GenericEvent; | |||
*/ | |||
class AddMissingIndices extends Command { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** @var EventDispatcherInterface */ | |||
private $dispatcher; | |||
public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) { | |||
public function __construct(Connection $connection, EventDispatcherInterface $dispatcher) { | |||
parent::__construct(); | |||
$this->connection = $connection; |
@@ -26,6 +26,7 @@ declare(strict_types=1); | |||
namespace OC\Core\Command\Db; | |||
use OC\DB\Connection; | |||
use OC\DB\SchemaWrapper; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -44,13 +45,13 @@ use Symfony\Component\EventDispatcher\GenericEvent; | |||
*/ | |||
class AddMissingPrimaryKeys extends Command { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** @var EventDispatcherInterface */ | |||
private $dispatcher; | |||
public function __construct(IDBConnection $connection, EventDispatcherInterface $dispatcher) { | |||
public function __construct(Connection $connection, EventDispatcherInterface $dispatcher) { | |||
parent::__construct(); | |||
$this->connection = $connection; |
@@ -34,8 +34,8 @@ namespace OC\Core\Command\Db; | |||
use Doctrine\DBAL\Platforms\SqlitePlatform; | |||
use Doctrine\DBAL\Types\Type; | |||
use Doctrine\DBAL\Types\Types; | |||
use OC\DB\Connection; | |||
use OC\DB\SchemaWrapper; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Command\Command; | |||
use Symfony\Component\Console\Input\InputInterface; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
@@ -43,13 +43,13 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; | |||
class ConvertFilecacheBigInt extends Command { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** | |||
* @param IDBConnection $connection | |||
* @param Connection $connection | |||
*/ | |||
public function __construct(IDBConnection $connection) { | |||
public function __construct(Connection $connection) { | |||
$this->connection = $connection; | |||
parent::__construct(); | |||
} |
@@ -24,7 +24,7 @@ | |||
namespace OC\Core\Command\Db; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\MySQLPlatform; | |||
use OC\DB\MySqlTools; | |||
use OC\Migration\ConsoleOutput; | |||
use OC\Repair\Collation; | |||
@@ -70,7 +70,7 @@ class ConvertMysqlToMB4 extends Command { | |||
} | |||
protected function execute(InputInterface $input, OutputInterface $output): int { | |||
if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) { | |||
if (!$this->connection->getDatabasePlatform() instanceof MySQLPlatform) { | |||
$output->writeln("This command is only valid for MySQL/MariaDB databases."); | |||
return 1; | |||
} |
@@ -33,9 +33,10 @@ | |||
namespace OC\Core\Command\Db; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Schema\AbstractAsset; | |||
use Doctrine\DBAL\Schema\Table; | |||
use Doctrine\DBAL\Types\Type; | |||
use Doctrine\DBAL\Types\Types; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionFactory; | |||
use OC\DB\MigrationService; | |||
@@ -52,6 +53,8 @@ use Symfony\Component\Console\Input\InputOption; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
use Symfony\Component\Console\Question\ConfirmationQuestion; | |||
use Symfony\Component\Console\Question\Question; | |||
use function preg_match; | |||
use function preg_quote; | |||
class ConvertType extends Command implements CompletionAwareInterface { | |||
/** | |||
@@ -192,7 +195,8 @@ class ConvertType extends Command implements CompletionAwareInterface { | |||
$this->validateInput($input, $output); | |||
$this->readPassword($input, $output); | |||
$fromDB = \OC::$server->getDatabaseConnection(); | |||
/** @var Connection $fromDB */ | |||
$fromDB = \OC::$server->get(Connection::class); | |||
$toDB = $this->getToDBConnection($input, $output); | |||
if ($input->getOption('clear-schema')) { | |||
@@ -283,9 +287,14 @@ class ConvertType extends Command implements CompletionAwareInterface { | |||
} | |||
protected function getTables(Connection $db) { | |||
$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; | |||
$db->getConfiguration()-> | |||
setFilterSchemaAssetsExpression($filterExpression); | |||
$db->getConfiguration()->setSchemaAssetsFilter(function ($asset) { | |||
/** @var string|AbstractAsset $asset */ | |||
$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; | |||
if ($asset instanceof AbstractAsset) { | |||
return preg_match($filterExpression, $asset->getName()) !== false; | |||
} | |||
return preg_match($filterExpression, $asset) !== false; | |||
}); | |||
return $db->getSchemaManager()->listTableNames(); | |||
} | |||
@@ -309,7 +318,7 @@ class ConvertType extends Command implements CompletionAwareInterface { | |||
$query->select($query->func()->count('*', 'num_entries')) | |||
->from($table->getName()); | |||
$result = $query->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$numChunks = ceil($count / $chunkSize); | |||
@@ -330,7 +339,7 @@ class ConvertType extends Command implements CompletionAwareInterface { | |||
try { | |||
$orderColumns = $table->getPrimaryKeyColumns(); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
$orderColumns = []; | |||
foreach ($table->getColumns() as $column) { | |||
$orderColumns[] = $column->getName(); | |||
@@ -384,11 +393,11 @@ class ConvertType extends Command implements CompletionAwareInterface { | |||
$type = $table->getColumn($columnName)->getType()->getName(); | |||
switch ($type) { | |||
case Type::BLOB: | |||
case Type::TEXT: | |||
case Types::BLOB: | |||
case Types::TEXT: | |||
$this->columnTypes[$tableName][$columnName] = IQueryBuilder::PARAM_LOB; | |||
break; | |||
case Type::BOOLEAN: | |||
case Types::BOOLEAN: | |||
$this->columnTypes[$tableName][$columnName] = IQueryBuilder::PARAM_BOOL; | |||
break; | |||
default: |
@@ -23,11 +23,10 @@ | |||
namespace OC\Core\Command\Db\Migrations; | |||
use OC\DB\Connection; | |||
use OC\DB\MigrationService; | |||
use OC\Migration\ConsoleOutput; | |||
use OCP\App\IAppManager; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; | |||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -37,23 +36,19 @@ use Symfony\Component\Console\Output\OutputInterface; | |||
class ExecuteCommand extends Command implements CompletionAwareInterface { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var IAppManager */ | |||
protected $appManager; | |||
/** | |||
* ExecuteCommand constructor. | |||
* | |||
* @param IDBConnection $connection | |||
* @param Connection $connection | |||
* @param IConfig $config | |||
* @param IAppManager $appManager | |||
*/ | |||
public function __construct(IDBConnection $connection, IAppManager $appManager, IConfig $config) { | |||
public function __construct(Connection $connection, IConfig $config) { | |||
$this->connection = $connection; | |||
$this->config = $config; | |||
@@ -25,10 +25,10 @@ | |||
namespace OC\Core\Command\Db\Migrations; | |||
use OC\DB\Connection; | |||
use OC\DB\MigrationService; | |||
use OC\Migration\ConsoleOutput; | |||
use OCP\App\IAppManager; | |||
use OCP\IDBConnection; | |||
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; | |||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -83,17 +83,17 @@ class {{classname}} extends SimpleMigrationStep { | |||
} | |||
'; | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
protected $connection; | |||
/** @var IAppManager */ | |||
protected $appManager; | |||
/** | |||
* @param IDBConnection $connection | |||
* @param Connection $connection | |||
* @param IAppManager $appManager | |||
*/ | |||
public function __construct(IDBConnection $connection, IAppManager $appManager) { | |||
public function __construct(Connection $connection, IAppManager $appManager) { | |||
$this->connection = $connection; | |||
$this->appManager = $appManager; | |||
@@ -26,12 +26,12 @@ | |||
namespace OC\Core\Command\Db\Migrations; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OC\DB\Connection; | |||
use OC\DB\MDB2SchemaReader; | |||
use OC\DB\MigrationService; | |||
use OC\Migration\ConsoleOutput; | |||
use OCP\App\IAppManager; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use Symfony\Component\Console\Input\InputInterface; | |||
use Symfony\Component\Console\Output\OutputInterface; | |||
@@ -40,7 +40,7 @@ class GenerateFromSchemaFileCommand extends GenerateCommand { | |||
/** @var IConfig */ | |||
protected $config; | |||
public function __construct(IConfig $config, IAppManager $appManager, IDBConnection $connection) { | |||
public function __construct(IConfig $config, IAppManager $appManager, Connection $connection) { | |||
parent::__construct($connection, $appManager); | |||
$this->config = $config; | |||
} |
@@ -22,9 +22,9 @@ | |||
namespace OC\Core\Command\Db\Migrations; | |||
use OC\DB\Connection; | |||
use OC\DB\MigrationService; | |||
use OC\Migration\ConsoleOutput; | |||
use OCP\IDBConnection; | |||
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; | |||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -34,13 +34,13 @@ use Symfony\Component\Console\Output\OutputInterface; | |||
class MigrateCommand extends Command implements CompletionAwareInterface { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** | |||
* @param IDBConnection $connection | |||
* @param Connection $connection | |||
*/ | |||
public function __construct(IDBConnection $connection) { | |||
public function __construct(Connection $connection) { | |||
$this->connection = $connection; | |||
parent::__construct(); | |||
} |
@@ -24,9 +24,9 @@ | |||
namespace OC\Core\Command\Db\Migrations; | |||
use OC\DB\Connection; | |||
use OC\DB\MigrationService; | |||
use OC\Migration\ConsoleOutput; | |||
use OCP\IDBConnection; | |||
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface; | |||
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; | |||
use Symfony\Component\Console\Command\Command; | |||
@@ -36,13 +36,10 @@ use Symfony\Component\Console\Output\OutputInterface; | |||
class StatusCommand extends Command implements CompletionAwareInterface { | |||
/** @var IDBConnection */ | |||
/** @var Connection */ | |||
private $connection; | |||
/** | |||
* @param IDBConnection $connection | |||
*/ | |||
public function __construct(IDBConnection $connection) { | |||
public function __construct(Connection $connection) { | |||
$this->connection = $connection; | |||
parent::__construct(); | |||
} |
@@ -60,7 +60,6 @@ class Version16000Date20190427105638 extends SimpleMigrationStep { | |||
* @param array $options | |||
* @return null|ISchemaWrapper | |||
* @throws \Doctrine\DBAL\Schema\SchemaException | |||
* @throws \Doctrine\DBAL\DBALException | |||
*/ | |||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { | |||
/** @var ISchemaWrapper $schema */ |
@@ -28,7 +28,7 @@ declare(strict_types=1); | |||
namespace OC\Core\Migrations; | |||
use Closure; | |||
use Doctrine\DBAL\Types\Type; | |||
use Doctrine\DBAL\Types\Types; | |||
use OCP\DB\ISchemaWrapper; | |||
use OCP\IDBConnection; | |||
use OCP\Migration\IOutput; | |||
@@ -55,20 +55,20 @@ class Version20000Date20201109081918 extends SimpleMigrationStep { | |||
if (!$schema->hasTable('storages_credentials')) { | |||
$table = $schema->createTable('storages_credentials'); | |||
$table->addColumn('id', Type::BIGINT, [ | |||
$table->addColumn('id', Types::BIGINT, [ | |||
'autoincrement' => true, | |||
'notnull' => true, | |||
'length' => 64, | |||
]); | |||
$table->addColumn('user', Type::STRING, [ | |||
$table->addColumn('user', Types::STRING, [ | |||
'notnull' => false, | |||
'length' => 64, | |||
]); | |||
$table->addColumn('identifier', Type::STRING, [ | |||
$table->addColumn('identifier', Types::STRING, [ | |||
'notnull' => true, | |||
'length' => 64, | |||
]); | |||
$table->addColumn('credentials', Type::TEXT, [ | |||
$table->addColumn('credentials', Types::TEXT, [ | |||
'notnull' => false, | |||
]); | |||
$table->setPrimaryKey(['id']); |
@@ -513,6 +513,7 @@ | |||
OC.SetupChecks.addGenericSetupCheck(data, 'OCA\\Settings\\SetupChecks\\PhpOutputBuffering', messages) | |||
OC.SetupChecks.addGenericSetupCheck(data, 'OCA\\Settings\\SetupChecks\\LegacySSEKeyFormat', messages) | |||
OC.SetupChecks.addGenericSetupCheck(data, 'OCA\\Settings\\SetupChecks\\CheckUserCertificates', messages) | |||
OC.SetupChecks.addGenericSetupCheck(data, 'OCA\\Settings\\SetupChecks\\SupportedDatabase', messages) | |||
} else { | |||
messages.push({ |
@@ -100,15 +100,15 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) { | |||
$application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig()))); | |||
$application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->getLogger())); | |||
$application->add(new OC\Core\Command\Db\ConvertFilecacheBigInt(\OC::$server->getDatabaseConnection())); | |||
$application->add(new OC\Core\Command\Db\AddMissingIndices(\OC::$server->getDatabaseConnection(), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\AddMissingColumns(\OC::$server->getDatabaseConnection(), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\AddMissingPrimaryKeys(\OC::$server->getDatabaseConnection(), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->getDatabaseConnection())); | |||
$application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->getDatabaseConnection())); | |||
$application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getAppManager())); | |||
$application->add(new OC\Core\Command\Db\Migrations\GenerateFromSchemaFileCommand(\OC::$server->getConfig(), \OC::$server->getAppManager(), \OC::$server->getDatabaseConnection())); | |||
$application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->getDatabaseConnection(), \OC::$server->getAppManager(), \OC::$server->getConfig())); | |||
$application->add(new OC\Core\Command\Db\ConvertFilecacheBigInt(\OC::$server->get(\OC\DB\Connection::class))); | |||
$application->add(new OC\Core\Command\Db\AddMissingIndices(\OC::$server->get(\OC\DB\Connection::class), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\AddMissingColumns(\OC::$server->get(\OC\DB\Connection::class), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\AddMissingPrimaryKeys(\OC::$server->get(\OC\DB\Connection::class), \OC::$server->getEventDispatcher())); | |||
$application->add(new OC\Core\Command\Db\Migrations\StatusCommand(\OC::$server->get(\OC\DB\Connection::class))); | |||
$application->add(new OC\Core\Command\Db\Migrations\MigrateCommand(\OC::$server->get(\OC\DB\Connection::class))); | |||
$application->add(new OC\Core\Command\Db\Migrations\GenerateCommand(\OC::$server->get(\OC\DB\Connection::class), \OC::$server->getAppManager())); | |||
$application->add(new OC\Core\Command\Db\Migrations\GenerateFromSchemaFileCommand(\OC::$server->getConfig(), \OC::$server->getAppManager(), \OC::$server->get(\OC\DB\Connection::class))); | |||
$application->add(new OC\Core\Command\Db\Migrations\ExecuteCommand(\OC::$server->get(\OC\DB\Connection::class), \OC::$server->getConfig())); | |||
$application->add(new OC\Core\Command\Encryption\Disable(\OC::$server->getConfig())); | |||
$application->add(new OC\Core\Command\Encryption\Enable(\OC::$server->getConfig(), \OC::$server->getEncryptionManager())); |
@@ -161,6 +161,8 @@ return array( | |||
'OCP\\Contacts\\ContactsMenu\\IProvider' => $baseDir . '/lib/public/Contacts/ContactsMenu/IProvider.php', | |||
'OCP\\Contacts\\Events\\ContactInteractedWithEvent' => $baseDir . '/lib/public/Contacts/Events/ContactInteractedWithEvent.php', | |||
'OCP\\Contacts\\IManager' => $baseDir . '/lib/public/Contacts/IManager.php', | |||
'OCP\\DB\\IPreparedStatement' => $baseDir . '/lib/public/DB/IPreparedStatement.php', | |||
'OCP\\DB\\IResult' => $baseDir . '/lib/public/DB/IResult.php', | |||
'OCP\\DB\\ISchemaWrapper' => $baseDir . '/lib/public/DB/ISchemaWrapper.php', | |||
'OCP\\DB\\QueryBuilder\\ICompositeExpression' => $baseDir . '/lib/public/DB/QueryBuilder/ICompositeExpression.php', | |||
'OCP\\DB\\QueryBuilder\\IExpressionBuilder' => $baseDir . '/lib/public/DB/QueryBuilder/IExpressionBuilder.php', | |||
@@ -948,10 +950,10 @@ return array( | |||
'OC\\DB\\AdapterPgSql' => $baseDir . '/lib/private/DB/AdapterPgSql.php', | |||
'OC\\DB\\AdapterSqlite' => $baseDir . '/lib/private/DB/AdapterSqlite.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\\MDB2SchemaManager' => $baseDir . '/lib/private/DB/MDB2SchemaManager.php', | |||
'OC\\DB\\MDB2SchemaReader' => $baseDir . '/lib/private/DB/MDB2SchemaReader.php', | |||
'OC\\DB\\MDB2SchemaWriter' => $baseDir . '/lib/private/DB/MDB2SchemaWriter.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', | |||
@@ -965,6 +967,7 @@ return array( | |||
'OC\\DB\\OracleMigrator' => $baseDir . '/lib/private/DB/OracleMigrator.php', | |||
'OC\\DB\\PgSqlTools' => $baseDir . '/lib/private/DB/PgSqlTools.php', | |||
'OC\\DB\\PostgreSqlMigrator' => $baseDir . '/lib/private/DB/PostgreSqlMigrator.php', | |||
'OC\\DB\\PreparedStatement' => $baseDir . '/lib/private/DB/PreparedStatement.php', | |||
'OC\\DB\\QueryBuilder\\CompositeExpression' => $baseDir . '/lib/private/DB/QueryBuilder/CompositeExpression.php', | |||
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\ExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php', | |||
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\MySqlExpressionBuilder' => $baseDir . '/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php', | |||
@@ -981,6 +984,7 @@ return array( | |||
'OC\\DB\\QueryBuilder\\QueryFunction' => $baseDir . '/lib/private/DB/QueryBuilder/QueryFunction.php', | |||
'OC\\DB\\QueryBuilder\\QuoteHelper' => $baseDir . '/lib/private/DB/QueryBuilder/QuoteHelper.php', | |||
'OC\\DB\\ReconnectWrapper' => $baseDir . '/lib/private/DB/ReconnectWrapper.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', |
@@ -190,6 +190,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OCP\\Contacts\\ContactsMenu\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IProvider.php', | |||
'OCP\\Contacts\\Events\\ContactInteractedWithEvent' => __DIR__ . '/../../..' . '/lib/public/Contacts/Events/ContactInteractedWithEvent.php', | |||
'OCP\\Contacts\\IManager' => __DIR__ . '/../../..' . '/lib/public/Contacts/IManager.php', | |||
'OCP\\DB\\IPreparedStatement' => __DIR__ . '/../../..' . '/lib/public/DB/IPreparedStatement.php', | |||
'OCP\\DB\\IResult' => __DIR__ . '/../../..' . '/lib/public/DB/IResult.php', | |||
'OCP\\DB\\ISchemaWrapper' => __DIR__ . '/../../..' . '/lib/public/DB/ISchemaWrapper.php', | |||
'OCP\\DB\\QueryBuilder\\ICompositeExpression' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/ICompositeExpression.php', | |||
'OCP\\DB\\QueryBuilder\\IExpressionBuilder' => __DIR__ . '/../../..' . '/lib/public/DB/QueryBuilder/IExpressionBuilder.php', | |||
@@ -977,10 +979,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\DB\\AdapterPgSql' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterPgSql.php', | |||
'OC\\DB\\AdapterSqlite' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterSqlite.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\\MDB2SchemaManager' => __DIR__ . '/../../..' . '/lib/private/DB/MDB2SchemaManager.php', | |||
'OC\\DB\\MDB2SchemaReader' => __DIR__ . '/../../..' . '/lib/private/DB/MDB2SchemaReader.php', | |||
'OC\\DB\\MDB2SchemaWriter' => __DIR__ . '/../../..' . '/lib/private/DB/MDB2SchemaWriter.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', | |||
@@ -994,6 +996,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\DB\\OracleMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/OracleMigrator.php', | |||
'OC\\DB\\PgSqlTools' => __DIR__ . '/../../..' . '/lib/private/DB/PgSqlTools.php', | |||
'OC\\DB\\PostgreSqlMigrator' => __DIR__ . '/../../..' . '/lib/private/DB/PostgreSqlMigrator.php', | |||
'OC\\DB\\PreparedStatement' => __DIR__ . '/../../..' . '/lib/private/DB/PreparedStatement.php', | |||
'OC\\DB\\QueryBuilder\\CompositeExpression' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/CompositeExpression.php', | |||
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\ExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php', | |||
'OC\\DB\\QueryBuilder\\ExpressionBuilder\\MySqlExpressionBuilder' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php', | |||
@@ -1010,6 +1013,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c | |||
'OC\\DB\\QueryBuilder\\QueryFunction' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/QueryFunction.php', | |||
'OC\\DB\\QueryBuilder\\QuoteHelper' => __DIR__ . '/../../..' . '/lib/private/DB/QueryBuilder/QuoteHelper.php', | |||
'OC\\DB\\ReconnectWrapper' => __DIR__ . '/../../..' . '/lib/private/DB/ReconnectWrapper.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', |
@@ -33,10 +33,10 @@ | |||
namespace OC; | |||
use OC\DB\Connection; | |||
use OC\DB\OracleConnection; | |||
use OCP\IAppConfig; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
/** | |||
* This class provides an easy way for apps to store config values in the | |||
@@ -68,7 +68,7 @@ class AppConfig implements IAppConfig { | |||
], | |||
]; | |||
/** @var \OCP\IDBConnection */ | |||
/** @var Connection */ | |||
protected $conn; | |||
/** @var array[] */ | |||
@@ -78,11 +78,10 @@ class AppConfig implements IAppConfig { | |||
private $configLoaded = false; | |||
/** | |||
* @param IDBConnection $conn | |||
* @param Connection $conn | |||
*/ | |||
public function __construct(IDBConnection $conn) { | |||
public function __construct(Connection $conn) { | |||
$this->conn = $conn; | |||
$this->configLoaded = false; | |||
} | |||
/** |
@@ -36,12 +36,11 @@ namespace OC\AppFramework\Http; | |||
use OC\AppFramework\Http; | |||
use OC\AppFramework\Middleware\MiddlewareDispatcher; | |||
use OC\AppFramework\Utility\ControllerMethodReflector; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionAdapter; | |||
use OCP\AppFramework\Controller; | |||
use OCP\AppFramework\Http\DataResponse; | |||
use OCP\AppFramework\Http\Response; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use OCP\IRequest; | |||
use Psr\Log\LoggerInterface; | |||
@@ -65,7 +64,7 @@ class Dispatcher { | |||
/** @var IConfig */ | |||
private $config; | |||
/** @var IDBConnection|Connection */ | |||
/** @var ConnectionAdapter */ | |||
private $connection; | |||
/** @var LoggerInterface */ | |||
@@ -79,7 +78,7 @@ class Dispatcher { | |||
* the arguments for the controller | |||
* @param IRequest $request the incoming request | |||
* @param IConfig $config | |||
* @param IDBConnection $connection | |||
* @param ConnectionAdapter $connection | |||
* @param LoggerInterface $logger | |||
*/ | |||
public function __construct(Http $protocol, | |||
@@ -87,7 +86,7 @@ class Dispatcher { | |||
ControllerMethodReflector $reflector, | |||
IRequest $request, | |||
IConfig $config, | |||
IDBConnection $connection, | |||
ConnectionAdapter $connection, | |||
LoggerInterface $logger) { | |||
$this->protocol = $protocol; | |||
$this->middlewareDispatcher = $middlewareDispatcher; | |||
@@ -122,13 +121,13 @@ class Dispatcher { | |||
$databaseStatsBefore = []; | |||
if ($this->config->getSystemValueBool('debug', false)) { | |||
$databaseStatsBefore = $this->connection->getStats(); | |||
$databaseStatsBefore = $this->connection->getInner()->getStats(); | |||
} | |||
$response = $this->executeController($controller, $methodName); | |||
if (!empty($databaseStatsBefore)) { | |||
$databaseStatsAfter = $this->connection->getStats(); | |||
$databaseStatsAfter = $this->connection->getInner()->getStats(); | |||
$numBuilt = $databaseStatsAfter['built'] - $databaseStatsBefore['built']; | |||
$numExecuted = $databaseStatsAfter['executed'] - $databaseStatsBefore['executed']; | |||
@@ -52,7 +52,7 @@ class Adapter { | |||
* @return int id of last insert statement | |||
*/ | |||
public function lastInsertId($table) { | |||
return $this->conn->realLastInsertId($table); | |||
return (int) $this->conn->realLastInsertId($table); | |||
} | |||
/** | |||
@@ -94,7 +94,7 @@ class Adapter { | |||
* If this is null or an empty array, all keys of $input will be compared | |||
* Please note: text fields (clob) must not be used in the compare array | |||
* @return int number of inserted rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371 | |||
*/ | |||
public function insertIfNotExist($table, $input, array $compare = null) { |
@@ -31,7 +31,10 @@ class AdapterPgSql extends Adapter { | |||
protected $compatModePre9_5 = null; | |||
public function lastInsertId($table) { | |||
return $this->conn->fetchColumn('SELECT lastval()'); | |||
$result = $this->conn->executeQuery('SELECT lastval()'); | |||
$val = $result->fetchOne(); | |||
$result->free(); | |||
return (int)$val; | |||
} | |||
public const UNIX_TIMESTAMP_REPLACEMENT = 'cast(extract(epoch from current_timestamp) as integer)'; | |||
@@ -62,7 +65,9 @@ class AdapterPgSql extends Adapter { | |||
return $this->compatModePre9_5; | |||
} | |||
$version = $this->conn->fetchColumn('SHOW SERVER_VERSION'); | |||
$result = $this->conn->executeQuery('SHOW SERVER_VERSION'); | |||
$version = $result->fetchOne(); | |||
$result->free(); | |||
$this->compatModePre9_5 = version_compare($version, '9.5', '<'); | |||
return $this->compatModePre9_5; |
@@ -62,7 +62,7 @@ class AdapterSqlite extends Adapter { | |||
* If this is null or an empty array, all keys of $input will be compared | |||
* Please note: text fields (clob) must not be used in the compare array | |||
* @return int number of inserted rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371 | |||
*/ | |||
public function insertIfNotExist($table, $input, array $compare = null) { |
@@ -1,4 +1,7 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
@@ -36,20 +39,21 @@ namespace OC\DB; | |||
use Doctrine\Common\EventManager; | |||
use Doctrine\DBAL\Cache\QueryCacheProfile; | |||
use Doctrine\DBAL\Configuration; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Driver; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Exception\ConstraintViolationException; | |||
use Doctrine\DBAL\Exception\NotNullConstraintViolationException; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\MySQLPlatform; | |||
use Doctrine\DBAL\Result; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use Doctrine\DBAL\Statement; | |||
use OC\DB\QueryBuilder\QueryBuilder; | |||
use OC\SystemConfig; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\IDBConnection; | |||
use OCP\ILogger; | |||
use OCP\PreConditionNotMetException; | |||
class Connection extends ReconnectWrapper implements IDBConnection { | |||
class Connection extends ReconnectWrapper { | |||
/** @var string */ | |||
protected $tablePrefix; | |||
@@ -73,9 +77,9 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
public function connect() { | |||
try { | |||
return parent::connect(); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
// throw a new exception to prevent leaking info from the stacktrace | |||
throw new DBALException('Failed to connect to the database: ' . $e->getMessage(), $e->getCode()); | |||
throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode()); | |||
} | |||
} | |||
@@ -88,13 +92,11 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
/** | |||
* Returns a QueryBuilder for the connection. | |||
* | |||
* @return \OCP\DB\QueryBuilder\IQueryBuilder | |||
*/ | |||
public function getQueryBuilder() { | |||
public function getQueryBuilder(): IQueryBuilder { | |||
$this->queriesBuilt++; | |||
return new QueryBuilder( | |||
$this, | |||
new ConnectionAdapter($this), | |||
$this->systemConfig, | |||
$this->logger | |||
); | |||
@@ -181,9 +183,9 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* @param string $statement The SQL statement to prepare. | |||
* @param int $limit | |||
* @param int $offset | |||
* @return \Doctrine\DBAL\Driver\Statement The prepared statement. | |||
* @return Statement The prepared statement. | |||
*/ | |||
public function prepare($statement, $limit = null, $offset = null) { | |||
public function prepare($statement, $limit = null, $offset = null): Statement { | |||
if ($limit === -1) { | |||
$limit = null; | |||
} | |||
@@ -208,18 +210,18 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* @param array $types The types the previous parameters are in. | |||
* @param \Doctrine\DBAL\Cache\QueryCacheProfile|null $qcp The query cache profile, optional. | |||
* | |||
* @return \Doctrine\DBAL\Driver\Statement The executed statement. | |||
* @return Result The executed statement. | |||
* | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
*/ | |||
public function executeQuery($sql, array $params = [], $types = [], QueryCacheProfile $qcp = null) { | |||
public function executeQuery(string $sql, array $params = [], $types = [], QueryCacheProfile $qcp = null): Result { | |||
$sql = $this->replaceTablePrefix($sql); | |||
$sql = $this->adapter->fixupStatement($sql); | |||
$this->queriesExecuted++; | |||
return parent::executeQuery($sql, $params, $types, $qcp); | |||
} | |||
public function executeUpdate($sql, array $params = [], array $types = []) { | |||
public function executeUpdate(string $sql, array $params = [], array $types = []): int { | |||
$sql = $this->replaceTablePrefix($sql); | |||
$sql = $this->adapter->fixupStatement($sql); | |||
$this->queriesExecuted++; | |||
@@ -236,11 +238,11 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* @param array $params The query parameters. | |||
* @param array $types The parameter types. | |||
* | |||
* @return integer The number of affected rows. | |||
* @return int The number of affected rows. | |||
* | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
*/ | |||
public function executeStatement($sql, array $params = [], array $types = []) { | |||
public function executeStatement($sql, array $params = [], array $types = []): int { | |||
$sql = $this->replaceTablePrefix($sql); | |||
$sql = $this->adapter->fixupStatement($sql); | |||
$this->queriesExecuted++; | |||
@@ -256,7 +258,7 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* columns or sequences. | |||
* | |||
* @param string $seqName Name of the sequence object from which the ID should be returned. | |||
* @return string A string representation of the last inserted ID. | |||
* @return string the last inserted ID. | |||
*/ | |||
public function lastInsertId($seqName = null) { | |||
if ($seqName) { | |||
@@ -281,7 +283,7 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* If this is null or an empty array, all keys of $input will be compared | |||
* Please note: text fields (clob) must not be used in the compare array | |||
* @return int number of inserted rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371 | |||
*/ | |||
public function insertIfNotExist($table, $input, array $compare = null) { | |||
@@ -310,7 +312,7 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* @param array $values (column name => value) | |||
* @param array $updatePreconditionValues ensure values match preconditions (column name => value) | |||
* @return int number of new rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws \Doctrine\DBAL\Exception | |||
* @throws PreConditionNotMetException | |||
*/ | |||
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []) { | |||
@@ -393,7 +395,7 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
public function getError() { | |||
$msg = $this->errorCode() . ': '; | |||
$errorInfo = $this->errorInfo(); | |||
if (is_array($errorInfo)) { | |||
if (!empty($errorInfo)) { | |||
$msg .= 'SQLSTATE = '.$errorInfo[0] . ', '; | |||
$msg .= 'Driver Code = '.$errorInfo[1] . ', '; | |||
$msg .= 'Driver Message = '.$errorInfo[2]; | |||
@@ -401,6 +403,14 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
return $msg; | |||
} | |||
public function errorCode() { | |||
return -1; | |||
} | |||
public function errorInfo() { | |||
return []; | |||
} | |||
/** | |||
* Drop a table from the database if it exists | |||
* | |||
@@ -462,7 +472,7 @@ class Connection extends ReconnectWrapper implements IDBConnection { | |||
* @since 11.0.0 | |||
*/ | |||
public function supports4ByteText() { | |||
if (!$this->getDatabasePlatform() instanceof MySqlPlatform) { | |||
if (!$this->getDatabasePlatform() instanceof MySQLPlatform) { | |||
return true; | |||
} | |||
return $this->getParams()['charset'] === 'utf8mb4'; |
@@ -0,0 +1,172 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/* | |||
* @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Platforms\AbstractPlatform; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OCP\DB\IPreparedStatement; | |||
use OCP\DB\IResult; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\IDBConnection; | |||
/** | |||
* 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 getQueryBuilder(): IQueryBuilder { | |||
return $this->inner->getQueryBuilder(); | |||
} | |||
public function prepare($sql, $limit = null, $offset = null): IPreparedStatement { | |||
return new PreparedStatement( | |||
$this->inner->prepare($sql, $limit, $offset) | |||
); | |||
} | |||
public function executeQuery(string $sql, array $params = [], $types = []): IResult { | |||
return new ResultAdapter( | |||
$this->inner->executeQuery($sql, $params, $types) | |||
); | |||
} | |||
public function executeUpdate(string $sql, array $params = [], array $types = []): int { | |||
return $this->inner->executeUpdate($sql, $params, $types); | |||
} | |||
public function executeStatement($sql, array $params = [], array $types = []): int { | |||
return $this->inner->executeStatement($sql, $params, $types); | |||
} | |||
public function lastInsertId(string $table): int { | |||
return (int) $this->inner->lastInsertId($table); | |||
} | |||
public function insertIfNotExist(string $table, array $input, array $compare = null) { | |||
return $this->inner->insertIfNotExist($table, $input, $compare); | |||
} | |||
public function insertIgnoreConflict(string $table, array $values): int { | |||
return $this->inner->insertIgnoreConflict($table, $values); | |||
} | |||
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int { | |||
return $this->inner->setValues($table, $keys, $values, $updatePreconditionValues); | |||
} | |||
public function lockTable($tableName): void { | |||
$this->inner->lockTable($tableName); | |||
} | |||
public function unlockTable(): void { | |||
$this->inner->unlockTable(); | |||
} | |||
public function beginTransaction(): void { | |||
$this->inner->beginTransaction(); | |||
} | |||
public function inTransaction(): bool { | |||
return $this->inner->inTransaction(); | |||
} | |||
public function commit(): void { | |||
$this->inner->commit(); | |||
} | |||
public function rollBack(): void { | |||
$this->inner->rollBack(); | |||
} | |||
public function getError(): string { | |||
return $this->inner->getError(); | |||
} | |||
public function errorCode() { | |||
return $this->inner->errorCode(); | |||
} | |||
public function errorInfo() { | |||
return $this->inner->errorInfo(); | |||
} | |||
public function connect(): bool { | |||
return $this->inner->connect(); | |||
} | |||
public function close(): void { | |||
$this->inner->close(); | |||
} | |||
public function quote($input, $type = IQueryBuilder::PARAM_STR) { | |||
return $this->inner->quote($input, $type); | |||
} | |||
/** | |||
* @todo we are leaking a 3rdparty type here | |||
*/ | |||
public function getDatabasePlatform(): AbstractPlatform { | |||
return $this->inner->getDatabasePlatform(); | |||
} | |||
public function dropTable(string $table): void { | |||
$this->inner->dropTable($table); | |||
} | |||
public function tableExists(string $table): bool { | |||
return $this->inner->tableExists($table); | |||
} | |||
public function escapeLikeParameter(string $param): string { | |||
return $this->inner->escapeLikeParameter($param); | |||
} | |||
public function supports4ByteText(): bool { | |||
return $this->inner->supports4ByteText(); | |||
} | |||
/** | |||
* @todo leaks a 3rdparty type | |||
*/ | |||
public function createSchema(): Schema { | |||
return $this->inner->createSchema(); | |||
} | |||
public function migrateToSchema(Schema $toSchema): void { | |||
$this->inner->migrateToSchema($toSchema); | |||
} | |||
public function getInner(): Connection { | |||
return $this->inner; | |||
} | |||
} |
@@ -31,35 +31,23 @@ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\MySQLPlatform; | |||
use Doctrine\DBAL\Platforms\OraclePlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform; | |||
use Doctrine\DBAL\Platforms\SqlitePlatform; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OCP\IDBConnection; | |||
class MDB2SchemaManager { | |||
/** @var \OC\DB\Connection $conn */ | |||
/** @var Connection $conn */ | |||
protected $conn; | |||
/** | |||
* @param IDBConnection $conn | |||
* @param Connection $conn | |||
*/ | |||
public function __construct($conn) { | |||
$this->conn = $conn; | |||
} | |||
/** | |||
* saves database scheme to xml file | |||
* @param string $file name of file | |||
* @return bool | |||
* | |||
* TODO: write more documentation | |||
*/ | |||
public function getDbStructure($file) { | |||
return \OC\DB\MDB2SchemaWriter::saveSchemaToFile($file, $this->conn); | |||
} | |||
/** | |||
* Creates tables from XML file | |||
* @param string $file file to read structure from | |||
@@ -86,9 +74,9 @@ class MDB2SchemaManager { | |||
return new SQLiteMigrator($this->conn, $random, $config, $dispatcher); | |||
} elseif ($platform instanceof OraclePlatform) { | |||
return new OracleMigrator($this->conn, $random, $config, $dispatcher); | |||
} elseif ($platform instanceof MySqlPlatform) { | |||
} elseif ($platform instanceof MySQLPlatform) { | |||
return new MySQLMigrator($this->conn, $random, $config, $dispatcher); | |||
} elseif ($platform instanceof PostgreSqlPlatform) { | |||
} elseif ($platform instanceof PostgreSQL94Platform) { | |||
return new PostgreSqlMigrator($this->conn, $random, $config, $dispatcher); | |||
} else { | |||
return new Migrator($this->conn, $random, $config, $dispatcher); |
@@ -1,181 +0,0 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* | |||
* @author Bart Visscher <bartv@thisnet.nl> | |||
* @author Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* @author Jörn Friedrich Dreyer <jfd@butonic.de> | |||
* @author Morris Jobke <hey@morrisjobke.de> | |||
* @author tbelau666 <thomas.belau@gmx.de> | |||
* @author Thomas Müller <thomas.mueller@tmit.eu> | |||
* | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Schema\Column; | |||
use Doctrine\DBAL\Schema\Index; | |||
class MDB2SchemaWriter { | |||
/** | |||
* @param string $file | |||
* @param \OC\DB\Connection $conn | |||
* @return bool | |||
*/ | |||
public static function saveSchemaToFile($file, \OC\DB\Connection $conn) { | |||
$config = \OC::$server->getConfig(); | |||
$xml = new \SimpleXMLElement('<database/>'); | |||
$xml->addChild('name', $config->getSystemValue('dbname', 'owncloud')); | |||
$xml->addChild('create', 'true'); | |||
$xml->addChild('overwrite', 'false'); | |||
if ($config->getSystemValue('dbtype', 'sqlite') === 'mysql' && $config->getSystemValue('mysql.utf8mb4', false)) { | |||
$xml->addChild('charset', 'utf8mb4'); | |||
} else { | |||
$xml->addChild('charset', 'utf8'); | |||
} | |||
// FIX ME: bloody work around | |||
if ($config->getSystemValue('dbtype', 'sqlite') === 'oci') { | |||
$filterExpression = '/^"' . preg_quote($conn->getPrefix()) . '/'; | |||
} else { | |||
$filterExpression = '/^' . preg_quote($conn->getPrefix()) . '/'; | |||
} | |||
$conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); | |||
foreach ($conn->getSchemaManager()->listTables() as $table) { | |||
self::saveTable($table, $xml->addChild('table')); | |||
} | |||
file_put_contents($file, $xml->asXML()); | |||
return true; | |||
} | |||
/** | |||
* @param \Doctrine\DBAL\Schema\Table $table | |||
* @param \SimpleXMLElement $xml | |||
*/ | |||
private static function saveTable($table, $xml) { | |||
$xml->addChild('name', $table->getName()); | |||
$declaration = $xml->addChild('declaration'); | |||
foreach ($table->getColumns() as $column) { | |||
self::saveColumn($column, $declaration->addChild('field')); | |||
} | |||
foreach ($table->getIndexes() as $index) { | |||
if ($index->getName() == 'PRIMARY') { | |||
$autoincrement = false; | |||
foreach ($index->getColumns() as $column) { | |||
if ($table->getColumn($column)->getAutoincrement()) { | |||
$autoincrement = true; | |||
} | |||
} | |||
if ($autoincrement) { | |||
continue; | |||
} | |||
} | |||
self::saveIndex($index, $declaration->addChild('index')); | |||
} | |||
} | |||
/** | |||
* @param Column $column | |||
* @param \SimpleXMLElement $xml | |||
*/ | |||
private static function saveColumn($column, $xml) { | |||
$xml->addChild('name', $column->getName()); | |||
switch ($column->getType()) { | |||
case 'SmallInt': | |||
case 'Integer': | |||
case 'BigInt': | |||
$xml->addChild('type', 'integer'); | |||
$default = $column->getDefault(); | |||
if (is_null($default) && $column->getAutoincrement()) { | |||
$default = '0'; | |||
} | |||
$xml->addChild('default', $default); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
if ($column->getAutoincrement()) { | |||
$xml->addChild('autoincrement', '1'); | |||
} | |||
if ($column->getUnsigned()) { | |||
$xml->addChild('unsigned', 'true'); | |||
} | |||
$length = '4'; | |||
if ($column->getType() == 'SmallInt') { | |||
$length = '2'; | |||
} elseif ($column->getType() == 'BigInt') { | |||
$length = '8'; | |||
} | |||
$xml->addChild('length', $length); | |||
break; | |||
case 'String': | |||
$xml->addChild('type', 'text'); | |||
$default = trim($column->getDefault()); | |||
if ($default === '') { | |||
$default = false; | |||
} | |||
$xml->addChild('default', $default); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
$xml->addChild('length', $column->getLength()); | |||
break; | |||
case 'Text': | |||
$xml->addChild('type', 'clob'); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
break; | |||
case 'Decimal': | |||
$xml->addChild('type', 'decimal'); | |||
$xml->addChild('default', $column->getDefault()); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
$xml->addChild('length', '15'); | |||
break; | |||
case 'Boolean': | |||
$xml->addChild('type', 'integer'); | |||
$xml->addChild('default', $column->getDefault()); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
$xml->addChild('length', '1'); | |||
break; | |||
case 'DateTime': | |||
$xml->addChild('type', 'timestamp'); | |||
$xml->addChild('default', $column->getDefault()); | |||
$xml->addChild('notnull', self::toBool($column->getNotnull())); | |||
break; | |||
} | |||
} | |||
/** | |||
* @param Index $index | |||
* @param \SimpleXMLElement $xml | |||
*/ | |||
private static function saveIndex($index, $xml) { | |||
$xml->addChild('name', $index->getName()); | |||
if ($index->isPrimary()) { | |||
$xml->addChild('primary', 'true'); | |||
} elseif ($index->isUnique()) { | |||
$xml->addChild('unique', 'true'); | |||
} | |||
foreach ($index->getColumns() as $column) { | |||
$field = $xml->addChild('field'); | |||
$field->addChild('name', $column); | |||
$field->addChild('sorting', 'ascending'); | |||
} | |||
} | |||
private static function toBool($bool) { | |||
return $bool ? 'true' : 'false'; | |||
} | |||
} |
@@ -30,7 +30,7 @@ namespace OC\DB; | |||
use Doctrine\DBAL\Exception\DriverException; | |||
use Doctrine\DBAL\Platforms\OraclePlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSQL94Platform; | |||
use Doctrine\DBAL\Schema\Index; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use Doctrine\DBAL\Schema\SchemaException; | |||
@@ -42,7 +42,6 @@ use OC\IntegrityCheck\Helpers\AppLocator; | |||
use OC\Migration\SimpleOutput; | |||
use OCP\AppFramework\App; | |||
use OCP\AppFramework\QueryException; | |||
use OCP\IDBConnection; | |||
use OCP\Migration\IMigrationStep; | |||
use OCP\Migration\IOutput; | |||
@@ -65,12 +64,12 @@ class MigrationService { | |||
* MigrationService constructor. | |||
* | |||
* @param $appName | |||
* @param IDBConnection $connection | |||
* @param Connection $connection | |||
* @param AppLocator $appLocator | |||
* @param IOutput|null $output | |||
* @throws \Exception | |||
*/ | |||
public function __construct($appName, IDBConnection $connection, IOutput $output = null, AppLocator $appLocator = null) { | |||
public function __construct($appName, Connection $connection, IOutput $output = null, AppLocator $appLocator = null) { | |||
$this->appName = $appName; | |||
$this->connection = $connection; | |||
$this->output = $output; | |||
@@ -591,7 +590,7 @@ class MigrationService { | |||
$indexName = strtolower($primaryKey->getName()); | |||
$isUsingDefaultName = $indexName === 'primary'; | |||
if ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) { | |||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) { | |||
$defaultName = $table->getName() . '_pkey'; | |||
$isUsingDefaultName = strtolower($defaultName) === $indexName; | |||
@@ -31,7 +31,8 @@ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Schema\AbstractAsset; | |||
use Doctrine\DBAL\Schema\Comparator; | |||
use Doctrine\DBAL\Schema\Index; | |||
use Doctrine\DBAL\Schema\Schema; | |||
@@ -43,6 +44,7 @@ use OCP\IConfig; | |||
use OCP\Security\ISecureRandom; | |||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||
use Symfony\Component\EventDispatcher\GenericEvent; | |||
use function preg_match; | |||
class Migrator { | |||
@@ -101,34 +103,6 @@ class Migrator { | |||
return $script; | |||
} | |||
/** | |||
* @param Schema $targetSchema | |||
* @throws \OC\DB\MigrationException | |||
*/ | |||
public function checkMigrate(Schema $targetSchema) { | |||
$this->noEmit = true; | |||
/**@var \Doctrine\DBAL\Schema\Table[] $tables */ | |||
$tables = $targetSchema->getTables(); | |||
$filterExpression = $this->getFilterExpression(); | |||
$this->connection->getConfiguration()-> | |||
setFilterSchemaAssetsExpression($filterExpression); | |||
$existingTables = $this->connection->getSchemaManager()->listTableNames(); | |||
$step = 0; | |||
foreach ($tables as $table) { | |||
if (strpos($table->getName(), '.')) { | |||
list(, $tableName) = explode('.', $table->getName()); | |||
} else { | |||
$tableName = $table->getName(); | |||
} | |||
$this->emitCheckStep($tableName, $step++, count($tables)); | |||
// don't need to check for new tables | |||
if (array_search($tableName, $existingTables) !== false) { | |||
$this->checkTableMigrate($table); | |||
} | |||
} | |||
} | |||
/** | |||
* Create a unique name for the temporary table | |||
* | |||
@@ -160,7 +134,7 @@ class Migrator { | |||
try { | |||
$this->applySchema($schema); | |||
$this->dropTable($tmpName); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
// pgsql needs to commit it's failed transaction before doing anything else | |||
if ($this->connection->isTransactionActive()) { | |||
$this->connection->commit(); | |||
@@ -193,12 +167,18 @@ class Migrator { | |||
} | |||
// foreign keys are not supported so we just set it to an empty array | |||
return new Table($newName, $table->getColumns(), $newIndexes, [], 0, $table->getOptions()); | |||
return new Table($newName, $table->getColumns(), $newIndexes, [], [], $table->getOptions()); | |||
} | |||
public function createSchema() { | |||
$filterExpression = $this->getFilterExpression(); | |||
$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); | |||
$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) { | |||
/** @var string|AbstractAsset $asset */ | |||
$filterExpression = $this->getFilterExpression(); | |||
if ($asset instanceof AbstractAsset) { | |||
return preg_match($filterExpression, $asset->getName()) !== false; | |||
} | |||
return preg_match($filterExpression, $asset) !== false; | |||
}); | |||
return $this->connection->getSchemaManager()->createSchema(); | |||
} | |||
@@ -206,7 +186,6 @@ class Migrator { | |||
* @param Schema $targetSchema | |||
* @param \Doctrine\DBAL\Connection $connection | |||
* @return \Doctrine\DBAL\Schema\SchemaDiff | |||
* @throws DBALException | |||
*/ | |||
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { | |||
// adjust varchar columns with a length higher then getVarcharMaxLength to clob | |||
@@ -221,8 +200,14 @@ class Migrator { | |||
} | |||
} | |||
$filterExpression = $this->getFilterExpression(); | |||
$this->connection->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); | |||
$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) { | |||
/** @var string|AbstractAsset $asset */ | |||
$filterExpression = $this->getFilterExpression(); | |||
if ($asset instanceof AbstractAsset) { | |||
return preg_match($filterExpression, $asset->getName()) !== false; | |||
} | |||
return preg_match($filterExpression, $asset) !== false; | |||
}); | |||
$sourceSchema = $connection->getSchemaManager()->createSchema(); | |||
// remove tables we don't know about |
@@ -32,7 +32,7 @@ use OCP\IDBConnection; | |||
class MySqlTools { | |||
/** | |||
* @param Connection $connection | |||
* @param IDBConnection $connection | |||
* @return bool | |||
*/ | |||
public function supports4ByteCharset(IDBConnection $connection) { |
@@ -30,7 +30,7 @@ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Schema\Column; | |||
use Doctrine\DBAL\Schema\ColumnDiff; | |||
use Doctrine\DBAL\Schema\ForeignKeyConstraint; | |||
@@ -113,7 +113,7 @@ class OracleMigrator extends Migrator { | |||
* @param Schema $targetSchema | |||
* @param \Doctrine\DBAL\Connection $connection | |||
* @return \Doctrine\DBAL\Schema\SchemaDiff | |||
* @throws DBALException | |||
* @throws Exception | |||
*/ | |||
protected function getDiff(Schema $targetSchema, \Doctrine\DBAL\Connection $connection) { | |||
$schemaDiff = parent::getDiff($targetSchema, $connection); | |||
@@ -128,10 +128,10 @@ class OracleMigrator extends Migrator { | |||
array_map(function (Index $index) { | |||
return $this->quoteIndex($index); | |||
}, $table->getIndexes()), | |||
[], | |||
array_map(function (ForeignKeyConstraint $fck) { | |||
return $this->quoteForeignKeyConstraint($fck); | |||
}, $table->getForeignKeys()), | |||
0, | |||
$table->getOptions() | |||
); | |||
}, $schemaDiff->newTables); | |||
@@ -141,8 +141,8 @@ class OracleMigrator extends Migrator { | |||
$this->connection->quoteIdentifier($table->getName()), | |||
$table->getColumns(), | |||
$table->getIndexes(), | |||
[], | |||
$table->getForeignKeys(), | |||
0, | |||
$table->getOptions() | |||
); | |||
}, $schemaDiff->removedTables); |
@@ -26,7 +26,10 @@ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Schema\AbstractAsset; | |||
use OCP\IConfig; | |||
use function preg_match; | |||
use function preg_quote; | |||
/** | |||
* Various PostgreSQL specific helper functions. | |||
@@ -50,20 +53,30 @@ class PgSqlTools { | |||
* @return null | |||
*/ | |||
public function resynchronizeDatabaseSequences(Connection $conn) { | |||
$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; | |||
$databaseName = $conn->getDatabase(); | |||
$conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression); | |||
$conn->getConfiguration()->setSchemaAssetsFilter(function ($asset) { | |||
/** @var string|AbstractAsset $asset */ | |||
$filterExpression = '/^' . preg_quote($this->config->getSystemValue('dbtableprefix', 'oc_')) . '/'; | |||
if ($asset instanceof AbstractAsset) { | |||
return preg_match($filterExpression, $asset->getName()) !== false; | |||
} | |||
return preg_match($filterExpression, $asset) !== false; | |||
}); | |||
foreach ($conn->getSchemaManager()->listSequences() as $sequence) { | |||
$sequenceName = $sequence->getName(); | |||
$sqlInfo = 'SELECT table_schema, table_name, column_name | |||
FROM information_schema.columns | |||
WHERE column_default = ? AND table_catalog = ?'; | |||
$sequenceInfo = $conn->fetchAssoc($sqlInfo, [ | |||
$result = $conn->executeQuery($sqlInfo, [ | |||
"nextval('$sequenceName'::regclass)", | |||
$databaseName | |||
]); | |||
$sequenceInfo = $result->fetchAssociative(); | |||
$result->free(); | |||
/** @var string $tableName */ | |||
$tableName = $sequenceInfo['table_name']; | |||
/** @var string $columnName */ | |||
$columnName = $sequenceInfo['column_name']; | |||
$sqlMaxId = "SELECT MAX($columnName) FROM $tableName"; | |||
$sqlSetval = "SELECT setval('$sequenceName', ($sqlMaxId))"; |
@@ -0,0 +1,101 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/* | |||
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\ParameterType; | |||
use Doctrine\DBAL\Statement; | |||
use OCP\DB\IPreparedStatement; | |||
use OCP\DB\IResult; | |||
use PDO; | |||
/** | |||
* Adapts our public API to what doctrine/dbal exposed with 2.6 | |||
* | |||
* The old dbal statement had stateful methods e.g. to fetch data from an executed | |||
* prepared statement. To provide backwards compatibility to apps we need to make | |||
* this class stateful. As soon as those now deprecated exposed methods are gone, | |||
* we can limit the API of this adapter to the methods that map to the direct dbal | |||
* methods without much magic. | |||
*/ | |||
class PreparedStatement implements IPreparedStatement { | |||
/** @var Statement */ | |||
private $statement; | |||
/** @var IResult|null */ | |||
private $result; | |||
public function __construct(Statement $statement) { | |||
$this->statement = $statement; | |||
} | |||
public function closeCursor(): bool { | |||
$this->getResult()->closeCursor(); | |||
return true; | |||
} | |||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) { | |||
return $this->getResult()->fetch($fetchMode); | |||
} | |||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array { | |||
return $this->getResult()->fetchAll($fetchMode); | |||
} | |||
public function fetchColumn() { | |||
return $this->getResult()->fetchOne(); | |||
} | |||
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 bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool { | |||
return $this->statement->bindParam($param, $variable, $type, $length); | |||
} | |||
public function execute($params = null): IResult { | |||
return ($this->result = new ResultAdapter($this->statement->execute($params))); | |||
} | |||
public function rowCount(): int { | |||
return $this->getResult()->rowCount(); | |||
} | |||
private function getResult(): IResult { | |||
if ($this->result !== null) { | |||
return $this->result; | |||
} | |||
throw new Exception("You have to execute the prepared statement before accessing the results"); | |||
} | |||
} |
@@ -27,6 +27,7 @@ | |||
namespace OC\DB\QueryBuilder\ExpressionBuilder; | |||
use Doctrine\DBAL\Query\Expression\ExpressionBuilder as DoctrineExpressionBuilder; | |||
use OC\DB\ConnectionAdapter; | |||
use OC\DB\QueryBuilder\CompositeExpression; | |||
use OC\DB\QueryBuilder\FunctionBuilder\FunctionBuilder; | |||
use OC\DB\QueryBuilder\Literal; | |||
@@ -55,13 +56,13 @@ class ExpressionBuilder implements IExpressionBuilder { | |||
/** | |||
* Initializes a new <tt>ExpressionBuilder</tt>. | |||
* | |||
* @param IDBConnection $connection | |||
* @param ConnectionAdapter $connection | |||
* @param IQueryBuilder $queryBuilder | |||
*/ | |||
public function __construct(IDBConnection $connection, IQueryBuilder $queryBuilder) { | |||
public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryBuilder) { | |||
$this->connection = $connection; | |||
$this->helper = new QuoteHelper(); | |||
$this->expressionBuilder = new DoctrineExpressionBuilder($connection); | |||
$this->expressionBuilder = new DoctrineExpressionBuilder($connection->getInner()); | |||
$this->functionBuilder = $queryBuilder->func(); | |||
} | |||
@@ -24,9 +24,8 @@ | |||
namespace OC\DB\QueryBuilder\ExpressionBuilder; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionAdapter; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\IDBConnection; | |||
class MySqlExpressionBuilder extends ExpressionBuilder { | |||
@@ -34,13 +33,13 @@ class MySqlExpressionBuilder extends ExpressionBuilder { | |||
protected $charset; | |||
/** | |||
* @param \OCP\IDBConnection|Connection $connection | |||
* @param ConnectionAdapter $connection | |||
* @param IQueryBuilder $queryBuilder | |||
*/ | |||
public function __construct(IDBConnection $connection, IQueryBuilder $queryBuilder) { | |||
public function __construct(ConnectionAdapter $connection, IQueryBuilder $queryBuilder) { | |||
parent::__construct($connection, $queryBuilder); | |||
$params = $connection->getParams(); | |||
$params = $connection->getInner()->getParams(); | |||
$this->charset = isset($params['charset']) ? $params['charset'] : 'utf8'; | |||
} | |||
@@ -30,11 +30,12 @@ | |||
namespace OC\DB\QueryBuilder; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform; | |||
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\OracleConnection; | |||
use OC\DB\ConnectionAdapter; | |||
use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder; | |||
use OC\DB\QueryBuilder\ExpressionBuilder\MySqlExpressionBuilder; | |||
use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder; | |||
@@ -44,17 +45,18 @@ use OC\DB\QueryBuilder\FunctionBuilder\FunctionBuilder; | |||
use OC\DB\QueryBuilder\FunctionBuilder\OCIFunctionBuilder; | |||
use OC\DB\QueryBuilder\FunctionBuilder\PgSqlFunctionBuilder; | |||
use OC\DB\QueryBuilder\FunctionBuilder\SqliteFunctionBuilder; | |||
use OC\DB\ResultAdapter; | |||
use OC\SystemConfig; | |||
use OCP\DB\IResult; | |||
use OCP\DB\QueryBuilder\ILiteral; | |||
use OCP\DB\QueryBuilder\IParameter; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\DB\QueryBuilder\IQueryFunction; | |||
use OCP\IDBConnection; | |||
use OCP\ILogger; | |||
class QueryBuilder implements IQueryBuilder { | |||
/** @var \OCP\IDBConnection */ | |||
/** @var ConnectionAdapter */ | |||
private $connection; | |||
/** @var SystemConfig */ | |||
@@ -78,15 +80,15 @@ class QueryBuilder implements IQueryBuilder { | |||
/** | |||
* Initializes a new QueryBuilder. | |||
* | |||
* @param IDBConnection $connection | |||
* @param ConnectionAdapter $connection | |||
* @param SystemConfig $systemConfig | |||
* @param ILogger $logger | |||
*/ | |||
public function __construct(IDBConnection $connection, SystemConfig $systemConfig, ILogger $logger) { | |||
public function __construct(ConnectionAdapter $connection, SystemConfig $systemConfig, ILogger $logger) { | |||
$this->connection = $connection; | |||
$this->systemConfig = $systemConfig; | |||
$this->logger = $logger; | |||
$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection); | |||
$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection->getInner()); | |||
$this->helper = new QuoteHelper(); | |||
} | |||
@@ -118,17 +120,20 @@ class QueryBuilder implements IQueryBuilder { | |||
* @return \OCP\DB\QueryBuilder\IExpressionBuilder | |||
*/ | |||
public function expr() { | |||
if ($this->connection instanceof OracleConnection) { | |||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { | |||
return new OCIExpressionBuilder($this->connection, $this); | |||
} elseif ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) { | |||
} | |||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) { | |||
return new PgSqlExpressionBuilder($this->connection, $this); | |||
} elseif ($this->connection->getDatabasePlatform() instanceof MySqlPlatform) { | |||
} | |||
if ($this->connection->getDatabasePlatform() instanceof MySQLPlatform) { | |||
return new MySqlExpressionBuilder($this->connection, $this); | |||
} elseif ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { | |||
} | |||
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { | |||
return new SqliteExpressionBuilder($this->connection, $this); | |||
} else { | |||
return new ExpressionBuilder($this->connection, $this); | |||
} | |||
return new ExpressionBuilder($this->connection, $this); | |||
} | |||
/** | |||
@@ -148,15 +153,17 @@ class QueryBuilder implements IQueryBuilder { | |||
* @return \OCP\DB\QueryBuilder\IFunctionBuilder | |||
*/ | |||
public function func() { | |||
if ($this->connection instanceof OracleConnection) { | |||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { | |||
return new OCIFunctionBuilder($this->helper); | |||
} elseif ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { | |||
} | |||
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { | |||
return new SqliteFunctionBuilder($this->helper); | |||
} elseif ($this->connection->getDatabasePlatform() instanceof PostgreSqlPlatform) { | |||
} | |||
if ($this->connection->getDatabasePlatform() instanceof PostgreSQL94Platform) { | |||
return new PgSqlFunctionBuilder($this->helper); | |||
} else { | |||
return new FunctionBuilder($this->helper); | |||
} | |||
return new FunctionBuilder($this->helper); | |||
} | |||
/** | |||
@@ -192,7 +199,7 @@ class QueryBuilder implements IQueryBuilder { | |||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} | |||
* for insert, update and delete statements. | |||
* | |||
* @return \Doctrine\DBAL\Driver\Statement|int | |||
* @return IResult|int | |||
*/ | |||
public function execute() { | |||
if ($this->systemConfig->getValue('log_query', false)) { | |||
@@ -246,7 +253,11 @@ class QueryBuilder implements IQueryBuilder { | |||
} | |||
} | |||
return $this->queryBuilder->execute(); | |||
$result = $this->queryBuilder->execute(); | |||
if (is_int($result)) { | |||
return $result; | |||
} | |||
return new ResultAdapter($result); | |||
} | |||
/** |
@@ -44,12 +44,12 @@ class ReconnectWrapper extends \Doctrine\DBAL\Connection { | |||
if ($this->lastConnectionCheck > $checkTime || $this->isTransactionActive()) { | |||
return parent::connect(); | |||
} else { | |||
$this->lastConnectionCheck = $now; | |||
if (!$this->ping()) { | |||
$this->close(); | |||
} | |||
return parent::connect(); | |||
} | |||
$this->lastConnectionCheck = $now; | |||
if (!$this->isConnected()) { | |||
$this->close(); | |||
} | |||
return parent::connect(); | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
<?php | |||
/* | |||
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
declare(strict_types=1); | |||
namespace OC\DB; | |||
use Doctrine\DBAL\Result; | |||
use OCP\DB\IResult; | |||
use PDO; | |||
/** | |||
* Adapts DBAL 2.6 API for DBAL 3.x for backwards compatibility of a leaked type | |||
*/ | |||
class ResultAdapter implements IResult { | |||
/** @var Result */ | |||
private $inner; | |||
public function __construct(Result $inner) { | |||
$this->inner = $inner; | |||
} | |||
public function closeCursor(): bool { | |||
$this->inner->free(); | |||
return true; | |||
} | |||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC) { | |||
return $this->inner->fetch($fetchMode); | |||
} | |||
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); | |||
} | |||
public function fetchColumn($columnIndex = 0) { | |||
return $this->inner->fetchOne(); | |||
} | |||
public function fetchOne() { | |||
return $this->inner->fetchOne(); | |||
} | |||
public function rowCount(): int { | |||
return $this->inner->rowCount(); | |||
} | |||
} |
@@ -26,49 +26,12 @@ | |||
namespace OC\DB; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use Doctrine\DBAL\Types\BigIntType; | |||
use Doctrine\DBAL\Types\Type; | |||
class SQLiteMigrator extends Migrator { | |||
/** | |||
* @param \Doctrine\DBAL\Schema\Schema $targetSchema | |||
* @throws \OC\DB\MigrationException | |||
* | |||
* For sqlite we simple make a copy of the entire database, and test the migration on that | |||
*/ | |||
public function checkMigrate(\Doctrine\DBAL\Schema\Schema $targetSchema) { | |||
$dbFile = $this->connection->getDatabase(); | |||
$tmpFile = $this->buildTempDatabase(); | |||
copy($dbFile, $tmpFile); | |||
$connectionParams = [ | |||
'path' => $tmpFile, | |||
'driver' => 'pdo_sqlite', | |||
]; | |||
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams); | |||
try { | |||
$this->applySchema($targetSchema, $conn); | |||
$conn->close(); | |||
unlink($tmpFile); | |||
} catch (DBALException $e) { | |||
$conn->close(); | |||
unlink($tmpFile); | |||
throw new MigrationException('', $e->getMessage()); | |||
} | |||
} | |||
/** | |||
* @return string | |||
*/ | |||
private function buildTempDatabase() { | |||
$dataDir = $this->config->getSystemValue("datadirectory", \OC::$SERVERROOT . '/data'); | |||
$tmpFile = uniqid("oc_"); | |||
return "$dataDir/$tmpFile.db"; | |||
} | |||
/** | |||
* @param Schema $targetSchema | |||
* @param \Doctrine\DBAL\Connection $connection |
@@ -60,8 +60,9 @@ class SQLiteSessionInit implements EventSubscriber { | |||
$sensitive = $this->caseSensitiveLike ? 'true' : 'false'; | |||
$args->getConnection()->executeUpdate('PRAGMA case_sensitive_like = ' . $sensitive); | |||
$args->getConnection()->executeUpdate('PRAGMA journal_mode = ' . $this->journalMode); | |||
/** @var \PDO $pdo */ | |||
$pdo = $args->getConnection()->getWrappedConnection(); | |||
/** @var \Doctrine\DBAL\Driver\PDO\Connection $connection */ | |||
$connection = $args->getConnection()->getWrappedConnection(); | |||
$pdo = $connection->getWrappedConnection(); | |||
$pdo->sqliteCreateFunction('md5', 'md5', 1); | |||
} | |||
@@ -26,11 +26,10 @@ namespace OC\DB; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OCP\DB\ISchemaWrapper; | |||
use OCP\IDBConnection; | |||
class SchemaWrapper implements ISchemaWrapper { | |||
/** @var IDBConnection|Connection */ | |||
/** @var Connection */ | |||
protected $connection; | |||
/** @var Schema */ | |||
@@ -39,10 +38,7 @@ class SchemaWrapper implements ISchemaWrapper { | |||
/** @var array */ | |||
protected $tablesToDelete = []; | |||
/** | |||
* @param IDBConnection $connection | |||
*/ | |||
public function __construct(IDBConnection $connection) { | |||
public function __construct(Connection $connection) { | |||
$this->connection = $connection; | |||
$this->schema = $this->connection->createSchema(); | |||
} |
@@ -39,8 +39,8 @@ | |||
namespace OC\Files\Cache; | |||
use Doctrine\DBAL\Driver\Statement; | |||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException; | |||
use OCP\DB\IResult; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\EventDispatcher\IEventDispatcher; | |||
use OCP\Files\Cache\CacheEntryInsertedEvent; | |||
@@ -486,7 +486,7 @@ class Cache implements ICache { | |||
->wherePath($file); | |||
$result = $query->execute(); | |||
$id = $result->fetchColumn(); | |||
$id = $result->fetchOne(); | |||
$result->closeCursor(); | |||
return $id === false ? -1 : (int)$id; | |||
@@ -746,7 +746,7 @@ class Cache implements ICache { | |||
->wherePath($file); | |||
$result = $query->execute(); | |||
$size = $result->fetchColumn(); | |||
$size = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($size !== false) { | |||
@@ -793,10 +793,10 @@ class Cache implements ICache { | |||
} | |||
/** | |||
* @param Statement $result | |||
* @param IResult $result | |||
* @return CacheEntry[] | |||
*/ | |||
private function searchResultToCacheEntries(Statement $result) { | |||
private function searchResultToCacheEntries(IResult $result): array { | |||
$files = $result->fetchAll(); | |||
return array_map(function (array $data) { | |||
@@ -870,7 +870,9 @@ class Cache implements ICache { | |||
} | |||
$result = $query->execute(); | |||
return $this->searchResultToCacheEntries($result); | |||
$cacheEntries = $this->searchResultToCacheEntries($result); | |||
$result->closeCursor(); | |||
return $cacheEntries; | |||
} | |||
/** | |||
@@ -912,7 +914,7 @@ class Cache implements ICache { | |||
->andWhere($query->expr()->lt('size', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT))); | |||
$result = $query->execute(); | |||
$size = (int)$result->fetchColumn(); | |||
$size = (int)$result->fetchOne(); | |||
$result->closeCursor(); | |||
return $size; | |||
@@ -1002,7 +1004,7 @@ class Cache implements ICache { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$path = $result->fetchColumn(); | |||
$path = $result->fetchOne(); | |||
$result->closeCursor(); | |||
return $path; | |||
@@ -1022,7 +1024,7 @@ class Cache implements ICache { | |||
->whereFileId($id); | |||
$result = $query->execute(); | |||
$path = $result->fetchColumn(); | |||
$path = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($path === false) { |
@@ -36,6 +36,7 @@ | |||
namespace OC\Files\Cache; | |||
use Doctrine\DBAL\Exception; | |||
use OC\Files\Filesystem; | |||
use OC\Hooks\BasicEmitter; | |||
use OCP\Files\Cache\IScanner; | |||
@@ -437,7 +438,7 @@ class Scanner extends BasicEmitter implements IScanner { | |||
$size += $data['size']; | |||
} | |||
} | |||
} catch (\Doctrine\DBAL\DBALException $ex) { | |||
} catch (Exception $ex) { | |||
// might happen if inserting duplicate while a scanning | |||
// process is running in parallel | |||
// log and ignore |
@@ -410,7 +410,7 @@ class Database extends ABackend implements | |||
} | |||
$result = $query->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count !== false) { | |||
@@ -442,7 +442,7 @@ class Database extends ABackend implements | |||
->andWhere($query->expr()->eq('gid', $query->createNamedParameter($gid), IQueryBuilder::PARAM_STR)); | |||
$result = $query->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count !== false) { | |||
@@ -467,7 +467,7 @@ class Database extends ABackend implements | |||
->where($query->expr()->eq('gid', $query->createNamedParameter($gid))); | |||
$result = $query->execute(); | |||
$displayName = $result->fetchColumn(); | |||
$displayName = $result->fetchOne(); | |||
$result->closeCursor(); | |||
return (string) $displayName; |
@@ -45,6 +45,7 @@ use OC\App\AppStore\Bundles\Bundle; | |||
use OC\App\AppStore\Fetcher\AppFetcher; | |||
use OC\AppFramework\Bootstrap\Coordinator; | |||
use OC\Archive\TAR; | |||
use OC\DB\Connection; | |||
use OC_App; | |||
use OC_DB; | |||
use OC_Helper; | |||
@@ -158,7 +159,7 @@ class Installer { | |||
OC_DB::updateDbFromStructure($basedir.'/appinfo/database.xml'); | |||
} | |||
} else { | |||
$ms = new \OC\DB\MigrationService($info['id'], \OC::$server->getDatabaseConnection()); | |||
$ms = new \OC\DB\MigrationService($info['id'], \OC::$server->get(Connection::class)); | |||
$ms->migrate('latest', true); | |||
} | |||
if ($previousVersion) { | |||
@@ -593,7 +594,7 @@ class Installer { | |||
); | |||
} | |||
} else { | |||
$ms = new \OC\DB\MigrationService($app, \OC::$server->getDatabaseConnection()); | |||
$ms = new \OC\DB\MigrationService($app, \OC::$server->get(Connection::class)); | |||
$ms->migrate('latest', true); | |||
} | |||
@@ -159,7 +159,7 @@ class DBLockingProvider extends AbstractLockingProvider { | |||
} | |||
$query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?'); | |||
$query->execute([$path]); | |||
$lockValue = (int)$query->fetchColumn(); | |||
$lockValue = (int)$query->fetchOne(); | |||
if ($type === self::LOCK_SHARED) { | |||
if ($this->isLocallyLocked($path)) { | |||
// if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db |
@@ -36,6 +36,8 @@ namespace OC; | |||
use OC\App\AppStore\Bundles\BundleFetcher; | |||
use OC\Avatar\AvatarManager; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionAdapter; | |||
use OC\Repair\AddBruteForceCleanupJob; | |||
use OC\Repair\AddCleanupUpdaterBackupsJob; | |||
use OC\Repair\CleanTags; | |||
@@ -210,13 +212,16 @@ class Repair implements IOutput { | |||
* @return IRepairStep[] | |||
*/ | |||
public static function getBeforeUpgradeRepairSteps() { | |||
$connection = \OC::$server->getDatabaseConnection(); | |||
/** @var Connection $connection */ | |||
$connection = \OC::$server->get(Connection::class); | |||
/** @var ConnectionAdapter $connectionAdapter */ | |||
$connectionAdapter = \OC::$server->get(ConnectionAdapter::class); | |||
$config = \OC::$server->getConfig(); | |||
$steps = [ | |||
new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true), | |||
new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connectionAdapter, true), | |||
new SqliteAutoincrement($connection), | |||
new SaveAccountsTableData($connection, $config), | |||
new DropAccountTermsTable($connection) | |||
new SaveAccountsTableData($connectionAdapter, $config), | |||
new DropAccountTermsTable($connectionAdapter) | |||
]; | |||
return $steps; |
@@ -28,7 +28,7 @@ | |||
namespace OC\Repair; | |||
use Doctrine\DBAL\Exception\DriverException; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\MySQLPlatform; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use OCP\ILogger; | |||
@@ -69,7 +69,7 @@ class Collation implements IRepairStep { | |||
* Fix mime types | |||
*/ | |||
public function run(IOutput $output) { | |||
if (!$this->connection->getDatabasePlatform() instanceof MySqlPlatform) { | |||
if (!$this->connection->getDatabasePlatform() instanceof MySQLPlatform) { | |||
$output->info('Not a mysql database -> nothing to do'); | |||
return; | |||
} |
@@ -30,8 +30,8 @@ declare(strict_types=1); | |||
namespace OC\Repair; | |||
use Doctrine\DBAL\Driver\Statement; | |||
use OCP\AppFramework\Utility\ITimeFactory; | |||
use OCP\DB\IResult; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
@@ -138,10 +138,8 @@ class RemoveLinkShares implements IRepairStep { | |||
/** | |||
* Get the cursor to fetch all the shares | |||
* | |||
* @return \Doctrine\DBAL\Driver\Statement | |||
*/ | |||
private function getShares(): Statement { | |||
private function getShares(): IResult { | |||
$subQuery = $this->connection->getQueryBuilder(); | |||
$subQuery->select('*') | |||
->from('share') | |||
@@ -160,7 +158,9 @@ class RemoveLinkShares implements IRepairStep { | |||
$query->expr()->eq('s2.share_type', $query->expr()->literal(2, IQueryBuilder::PARAM_INT)) | |||
)) | |||
->andWhere($query->expr()->eq('s1.item_source', 's2.item_source')); | |||
return $query->execute(); | |||
/** @var IResult $result */ | |||
$result = $query->execute(); | |||
return $result; | |||
} | |||
/** | |||
@@ -210,13 +210,13 @@ class RemoveLinkShares implements IRepairStep { | |||
private function repair(IOutput $output, int $total): void { | |||
$output->startProgress($total); | |||
$shareCursor = $this->getShares(); | |||
while ($data = $shareCursor->fetch()) { | |||
$shareResult = $this->getShares(); | |||
while ($data = $shareResult->fetch()) { | |||
$this->processShare($data); | |||
$output->advance(); | |||
} | |||
$output->finishProgress(); | |||
$shareCursor->closeCursor(); | |||
$shareResult->closeCursor(); | |||
// Notifiy all admins | |||
$adminGroup = $this->groupManager->get('admin'); |
@@ -71,7 +71,7 @@ class RepairMimeTypes implements IRepairStep { | |||
if (empty($this->folderMimeTypeId)) { | |||
$query->setParameter('mimetype', 'httpd/unix-directory'); | |||
$result = $query->execute(); | |||
$this->folderMimeTypeId = (int)$result->fetchColumn(); | |||
$this->folderMimeTypeId = (int)$result->fetchOne(); | |||
$result->closeCursor(); | |||
} | |||
@@ -88,7 +88,7 @@ class RepairMimeTypes implements IRepairStep { | |||
// get target mimetype id | |||
$query->setParameter('mimetype', $mimetype); | |||
$result = $query->execute(); | |||
$mimetypeId = (int)$result->fetchColumn(); | |||
$mimetypeId = (int)$result->fetchOne(); | |||
$result->closeCursor(); | |||
if (!$mimetypeId) { | |||
@@ -242,7 +242,7 @@ class RepairMimeTypes implements IRepairStep { | |||
if (version_compare($ocVersionFromBeforeUpdate, '20.0.0.5', '<') && $this->introduceOpenDocumentTemplates()) { | |||
$out->info('Fixed OpenDocument template mime types'); | |||
} | |||
if (version_compare($ocVersionFromBeforeUpdate, '21.0.0.7', '<') && $this->introduceOrgModeType()) { | |||
$out->info('Fixed orgmode mime types'); | |||
} |
@@ -77,6 +77,8 @@ use OC\Comments\ManagerFactory as CommentsManagerFactory; | |||
use OC\Contacts\ContactsMenu\ActionFactory; | |||
use OC\Contacts\ContactsMenu\ContactsStore; | |||
use OC\Dashboard\DashboardManager; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionAdapter; | |||
use OC\Diagnostics\EventLogger; | |||
use OC\Diagnostics\QueryLogger; | |||
use OC\EventDispatcher\SymfonyAdapter; | |||
@@ -792,7 +794,8 @@ class Server extends ServerContainer implements IServerContainer { | |||
/** @deprecated 19.0.0 */ | |||
$this->registerDeprecatedAlias('CredentialsManager', ICredentialsManager::class); | |||
$this->registerService(IDBConnection::class, function (Server $c) { | |||
$this->registerAlias(IDBConnection::class, ConnectionAdapter::class); | |||
$this->registerService(Connection::class, function (Server $c) { | |||
$systemConfig = $c->get(SystemConfig::class); | |||
$factory = new \OC\DB\ConnectionFactory($systemConfig); | |||
$type = $systemConfig->getValue('dbtype', 'sqlite'); |
@@ -29,6 +29,7 @@ | |||
namespace OC\Setup; | |||
use OC\DB\Connection; | |||
use OC\DB\ConnectionFactory; | |||
use OC\DB\MigrationService; | |||
use OC\SystemConfig; | |||
@@ -108,7 +109,7 @@ abstract class AbstractDatabase { | |||
* @param array $configOverwrite | |||
* @return \OC\DB\Connection | |||
*/ | |||
protected function connect(array $configOverwrite = []) { | |||
protected function connect(array $configOverwrite = []): Connection { | |||
$connectionParams = [ | |||
'host' => $this->dbHost, | |||
'user' => $this->dbUser, | |||
@@ -149,7 +150,7 @@ abstract class AbstractDatabase { | |||
if (!is_dir(\OC::$SERVERROOT."/core/Migrations")) { | |||
return; | |||
} | |||
$ms = new MigrationService('core', \OC::$server->getDatabaseConnection()); | |||
$ms = new MigrationService('core', \OC::$server->get(Connection::class)); | |||
$ms->migrate('latest', true); | |||
} | |||
} |
@@ -31,6 +31,7 @@ | |||
namespace OC\Setup; | |||
use OC\DB\ConnectionAdapter; | |||
use OC\DB\MySqlTools; | |||
use OCP\IDBConnection; | |||
use OCP\ILogger; | |||
@@ -45,12 +46,12 @@ class MySQL extends AbstractDatabase { | |||
// detect mb4 | |||
$tools = new MySqlTools(); | |||
if ($tools->supports4ByteCharset($connection)) { | |||
if ($tools->supports4ByteCharset(new ConnectionAdapter($connection))) { | |||
$this->config->setValue('mysql.utf8mb4', true); | |||
$connection = $this->connect(['dbname' => null]); | |||
} | |||
$this->createSpecificUser($username, $connection); | |||
$this->createSpecificUser($username, new ConnectionAdapter($connection)); | |||
//create the database | |||
$this->createDatabase($connection); | |||
@@ -156,27 +157,24 @@ class MySQL extends AbstractDatabase { | |||
$result = $connection->executeQuery($query, [$adminUser]); | |||
//current dbuser has admin rights | |||
if ($result) { | |||
$data = $result->fetchAll(); | |||
//new dbuser does not exist | |||
if (count($data) === 0) { | |||
//use the admin login data for the new database user | |||
$this->dbUser = $adminUser; | |||
//create a random password so we don't need to store the admin password in the config file | |||
$this->dbPassword = $this->random->generate(30); | |||
$this->createDBUser($connection); | |||
break; | |||
} else { | |||
//repeat with different username | |||
$length = strlen((string)$i); | |||
$adminUser = substr('oc_' . $username, 0, 16 - $length) . $i; | |||
$i++; | |||
} | |||
} else { | |||
$data = $result->fetchAll(); | |||
$result->closeCursor(); | |||
//new dbuser does not exist | |||
if (count($data) === 0) { | |||
//use the admin login data for the new database user | |||
$this->dbUser = $adminUser; | |||
//create a random password so we don't need to store the admin password in the config file | |||
$this->dbPassword = $this->random->generate(30); | |||
$this->createDBUser($connection); | |||
break; | |||
} else { | |||
//repeat with different username | |||
$length = strlen((string)$i); | |||
$adminUser = substr('oc_' . $username, 0, 16 - $length) . $i; | |||
$i++; | |||
} | |||
} | |||
} |
@@ -30,8 +30,8 @@ | |||
namespace OC\Setup; | |||
use OC\DatabaseException; | |||
use OC\DB\Connection; | |||
use OC\DB\QueryBuilder\Literal; | |||
use OCP\IDBConnection; | |||
class PostgreSQL extends AbstractDatabase { | |||
public $dbprettyname = 'PostgreSQL'; | |||
@@ -103,7 +103,7 @@ class PostgreSQL extends AbstractDatabase { | |||
} | |||
} | |||
private function createDatabase(IDBConnection $connection) { | |||
private function createDatabase(Connection $connection) { | |||
if (!$this->databaseExists($connection)) { | |||
//The database does not exists... let's create it | |||
$query = $connection->prepare("CREATE DATABASE " . addslashes($this->dbName) . " OWNER " . addslashes($this->dbUser)); | |||
@@ -124,7 +124,7 @@ class PostgreSQL extends AbstractDatabase { | |||
} | |||
} | |||
private function userExists(IDBConnection $connection) { | |||
private function userExists(Connection $connection) { | |||
$builder = $connection->getQueryBuilder(); | |||
$builder->automaticTablePrefix(false); | |||
$query = $builder->select('*') | |||
@@ -134,7 +134,7 @@ class PostgreSQL extends AbstractDatabase { | |||
return $result->rowCount() > 0; | |||
} | |||
private function databaseExists(IDBConnection $connection) { | |||
private function databaseExists(Connection $connection) { | |||
$builder = $connection->getQueryBuilder(); | |||
$builder->automaticTablePrefix(false); | |||
$query = $builder->select('datname') | |||
@@ -144,7 +144,7 @@ class PostgreSQL extends AbstractDatabase { | |||
return $result->rowCount() > 0; | |||
} | |||
private function createDBUser(IDBConnection $connection) { | |||
private function createDBUser(Connection $connection) { | |||
$dbUser = $this->dbUser; | |||
try { | |||
$i = 1; |
@@ -230,10 +230,6 @@ class Tags implements ITags { | |||
} | |||
$entries[$objId][] = $row['category']; | |||
} | |||
if ($result === null) { | |||
\OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OC::$server->getDatabaseConnection()->getError(), ILogger::ERROR); | |||
return false; | |||
} | |||
} | |||
} catch (\Exception $e) { | |||
\OC::$server->getLogger()->logException($e, [ |
@@ -37,6 +37,7 @@ | |||
namespace OC; | |||
use OC\DB\Connection; | |||
use OC\DB\MigrationService; | |||
use OC\Hooks\BasicEmitter; | |||
use OC\IntegrityCheck\Checker; | |||
@@ -298,7 +299,7 @@ class Updater extends BasicEmitter { | |||
$this->emit('\OC\Updater', 'dbUpgradeBefore'); | |||
// execute core migrations | |||
$ms = new MigrationService('core', \OC::$server->getDatabaseConnection()); | |||
$ms = new MigrationService('core', \OC::$server->get(Connection::class)); | |||
$ms->migrate(); | |||
$this->emit('\OC\Updater', 'dbUpgrade'); |
@@ -436,7 +436,7 @@ class Database extends ABackend implements | |||
->from($this->table); | |||
$result = $query->execute(); | |||
return $result->fetchColumn(); | |||
return $result->fetchOne(); | |||
} | |||
/** |
@@ -491,7 +491,7 @@ class Manager extends PublicEmitter implements IUserManager { | |||
$result = $queryBuilder->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count !== false) { | |||
@@ -521,7 +521,7 @@ class Manager extends PublicEmitter implements IUserManager { | |||
->andWhere($queryBuilder->expr()->in('gid', $queryBuilder->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY))); | |||
$result = $queryBuilder->execute(); | |||
$count = $result->fetchColumn(); | |||
$count = $result->fetchOne(); | |||
$result->closeCursor(); | |||
if ($count !== false) { | |||
@@ -549,7 +549,7 @@ class Manager extends PublicEmitter implements IUserManager { | |||
$query = $queryBuilder->execute(); | |||
$result = (int)$query->fetchColumn(); | |||
$result = (int)$query->fetchOne(); | |||
$query->closeCursor(); | |||
return $result; |
@@ -989,7 +989,7 @@ class OC_App { | |||
if (file_exists($appPath . '/appinfo/database.xml')) { | |||
OC_DB::updateDbFromStructure($appPath . '/appinfo/database.xml'); | |||
} else { | |||
$ms = new MigrationService($appId, \OC::$server->getDatabaseConnection()); | |||
$ms = new MigrationService($appId, \OC::$server->get(\OC\DB\Connection::class)); | |||
$ms->migrate(); | |||
} | |||
@@ -44,7 +44,7 @@ class OC_DB { | |||
* @return \OC\DB\MDB2SchemaManager | |||
*/ | |||
private static function getMDB2SchemaManager() { | |||
return new \OC\DB\MDB2SchemaManager(\OC::$server->getDatabaseConnection()); | |||
return new \OC\DB\MDB2SchemaManager(\OC::$server->get(\OC\DB\Connection::class)); | |||
} | |||
/** | |||
@@ -70,7 +70,7 @@ class OC_DB { | |||
// return the result | |||
try { | |||
$result = $connection->prepare($query, $limit, $offset); | |||
} catch (\Doctrine\DBAL\DBALException $e) { | |||
} catch (\Doctrine\DBAL\Exception $e) { | |||
throw new \OC\DatabaseException($e->getMessage()); | |||
} | |||
// differentiate between query and manipulation | |||
@@ -159,18 +159,6 @@ class OC_DB { | |||
return $result; | |||
} | |||
/** | |||
* saves database schema to xml file | |||
* @param string $file name of file | |||
* @return bool | |||
* | |||
* TODO: write more documentation | |||
*/ | |||
public static function getDbStructure($file) { | |||
$schemaManager = self::getMDB2SchemaManager(); | |||
return $schemaManager->getDbStructure($file); | |||
} | |||
/** | |||
* Creates tables from XML file | |||
* @param string $file file to read structure from | |||
@@ -211,7 +199,7 @@ class OC_DB { | |||
} | |||
/** | |||
* check if a result is an error and throws an exception, works with \Doctrine\DBAL\DBALException | |||
* check if a result is an error and throws an exception, works with \Doctrine\DBAL\Exception | |||
* @param mixed $result | |||
* @param string $message | |||
* @return void |
@@ -28,6 +28,8 @@ | |||
* | |||
*/ | |||
use OCP\DB\IPreparedStatement; | |||
/** | |||
* small wrapper around \Doctrine\DBAL\Driver\Statement to make it behave, more like an MDB2 Statement | |||
* | |||
@@ -38,17 +40,20 @@ | |||
* @method array fetchAll(integer $fetchMode = null); | |||
*/ | |||
class OC_DB_StatementWrapper { | |||
/** | |||
* @var \Doctrine\DBAL\Driver\Statement | |||
*/ | |||
/** @var IPreparedStatement */ | |||
private $statement = null; | |||
/** @var bool */ | |||
private $isManipulation = false; | |||
/** @var array */ | |||
private $lastArguments = []; | |||
/** | |||
* @param IPreparedStatement $statement | |||
* @param boolean $isManipulation | |||
*/ | |||
public function __construct($statement, $isManipulation) { | |||
public function __construct(IPreparedStatement $statement, $isManipulation) { | |||
$this->statement = $statement; | |||
$this->isManipulation = $isManipulation; | |||
} | |||
@@ -63,31 +68,34 @@ class OC_DB_StatementWrapper { | |||
/** | |||
* make execute return the result instead of a bool | |||
* | |||
* @param array $input | |||
* @param mixed[] $input | |||
* @return \OC_DB_StatementWrapper|int|bool | |||
* @deprecated | |||
*/ | |||
public function execute($input = []) { | |||
$this->lastArguments = $input; | |||
if (count($input) > 0) { | |||
$result = $this->statement->execute($input); | |||
} else { | |||
$result = $this->statement->execute(); | |||
} | |||
if ($result === false) { | |||
try { | |||
if (count($input) > 0) { | |||
$result = $this->statement->execute($input); | |||
} else { | |||
$result = $this->statement->execute(); | |||
} | |||
} catch (\Doctrine\DBAL\Exception $e) { | |||
return false; | |||
} | |||
if ($this->isManipulation) { | |||
return $this->statement->rowCount(); | |||
} else { | |||
return $this; | |||
} | |||
return $this; | |||
} | |||
/** | |||
* provide an alias for fetch | |||
* | |||
* @return mixed | |||
* @deprecated | |||
*/ | |||
public function fetchRow() { | |||
return $this->statement->fetch(); | |||
@@ -97,11 +105,11 @@ class OC_DB_StatementWrapper { | |||
* Provide a simple fetchOne. | |||
* | |||
* fetch single column from the next row | |||
* @param int $column the column number to fetch | |||
* @return string | |||
* @deprecated | |||
*/ | |||
public function fetchOne($column = 0) { | |||
return $this->statement->fetchColumn($column); | |||
public function fetchOne() { | |||
return $this->statement->fetchOne(); | |||
} | |||
/** |
@@ -993,7 +993,7 @@ class OC_Util { | |||
]; | |||
} | |||
} | |||
} catch (\Doctrine\DBAL\DBALException $e) { | |||
} catch (\Doctrine\DBAL\Exception $e) { | |||
$logger = \OC::$server->getLogger(); | |||
$logger->warning('Error occurred while checking PostgreSQL version, assuming >= 9'); | |||
$logger->logException($e); |
@@ -0,0 +1,127 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/* | |||
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
namespace OCP\DB; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\ParameterType; | |||
use PDO; | |||
/** | |||
* @since 21.0.0 | |||
*/ | |||
interface IPreparedStatement { | |||
/** | |||
* @return true | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::closeCursor on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function closeCursor(): bool; | |||
/** | |||
* @param int $fetchMode | |||
* | |||
* @return mixed | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetch on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC); | |||
/** | |||
* @param int $fetchMode | |||
* | |||
* @return mixed[] | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchAll on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC); | |||
/** | |||
* @return mixed | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchColumn on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function fetchColumn(); | |||
/** | |||
* @return mixed | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchOne on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function fetchOne(); | |||
/** | |||
* @param int|string $param | |||
* @param mixed $value | |||
* @param int $type | |||
* | |||
* @return bool | |||
* | |||
* @throws Exception | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function bindValue($param, $value, $type = ParameterType::STRING): bool; | |||
/** | |||
* @param int|string $param | |||
* @param mixed $variable | |||
* @param int $type | |||
* @param int|null $length | |||
* | |||
* @return bool | |||
* | |||
* @throws Exception | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool; | |||
/** | |||
* @param mixed[]|null $params | |||
* | |||
* @return IResult | |||
* | |||
* @since 21.0.0 | |||
* @throws Exception | |||
*/ | |||
public function execute($params = null): IResult; | |||
/** | |||
* @return int | |||
* | |||
* @since 21.0.0 | |||
* | |||
* @throws Exception | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::rowCount on the \OCP\DB\IResult returned by \OCP\IDBConnection::prepare | |||
*/ | |||
public function rowCount(): int; | |||
} |
@@ -0,0 +1,83 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/* | |||
* @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at> | |||
* | |||
* @license GNU AGPL version 3 or any later version | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License as | |||
* published by the Free Software Foundation, either version 3 of the | |||
* License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Affero General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Affero General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
namespace OCP\DB; | |||
use PDO; | |||
/** | |||
* @since 21.0.0 | |||
*/ | |||
interface IResult { | |||
/** | |||
* @return true | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function closeCursor(): bool; | |||
/** | |||
* @param int $fetchMode | |||
* | |||
* @return mixed | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function fetch(int $fetchMode = PDO::FETCH_ASSOC); | |||
/** | |||
* @param int $fetchMode (one of PDO::FETCH_ASSOC, PDO::FETCH_NUM or PDO::FETCH_COLUMN (2, 3 or 7) | |||
* | |||
* @return mixed[] | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function fetchAll(int $fetchMode = PDO::FETCH_ASSOC): array; | |||
/** | |||
* @return mixed | |||
* | |||
* @since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\IResult::fetchOne | |||
*/ | |||
public function fetchColumn(); | |||
/** | |||
* @param int $columnIndex | |||
* | |||
* @return false|mixed | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function fetchOne(); | |||
/** | |||
* @return int | |||
* | |||
* @since 21.0.0 | |||
*/ | |||
public function rowCount(): int; | |||
} |
@@ -29,6 +29,7 @@ | |||
namespace OCP\DB\QueryBuilder; | |||
use Doctrine\DBAL\Connection; | |||
use OCP\DB\IResult; | |||
/** | |||
* This class provides a wrapper around Doctrine's QueryBuilder | |||
@@ -148,7 +149,11 @@ interface IQueryBuilder { | |||
* Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} | |||
* for insert, update and delete statements. | |||
* | |||
* @return \Doctrine\DBAL\Driver\Statement|int | |||
* Warning: until Nextcloud 20, this method could return a \Doctrine\DBAL\Driver\Statement but since | |||
* that interface changed in a breaking way the adapter \OCP\DB\QueryBuilder\IStatement is returned | |||
* to bridge old code to the new API | |||
* | |||
* @return IResult|int | |||
* @since 8.2.0 | |||
*/ | |||
public function execute(); |
@@ -39,7 +39,10 @@ | |||
namespace OCP; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OCP\DB\IPreparedStatement; | |||
use OCP\DB\IResult; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
/** | |||
@@ -68,10 +71,11 @@ interface IDBConnection { | |||
* @param string $sql the sql query with ? placeholder for params | |||
* @param int $limit the maximum number of rows | |||
* @param int $offset from which row we want to start | |||
* @return \Doctrine\DBAL\Driver\Statement The prepared statement. | |||
* @return IPreparedStatement The prepared statement. | |||
* @since 6.0.0 | |||
* @throws Exception since 21.0.0 | |||
*/ | |||
public function prepare($sql, $limit = null, $offset = null); | |||
public function prepare($sql, $limit = null, $offset = null): IPreparedStatement; | |||
/** | |||
* Executes an, optionally parameterized, SQL query. | |||
@@ -82,10 +86,11 @@ interface IDBConnection { | |||
* @param string $sql The SQL query to execute. | |||
* @param string[] $params The parameters to bind to the query, if any. | |||
* @param array $types The types the previous parameters are in. | |||
* @return \Doctrine\DBAL\Driver\Statement The executed statement. | |||
* @return IResult The executed statement. | |||
* @since 8.0.0 | |||
* @throws Exception since 21.0.0 | |||
*/ | |||
public function executeQuery($sql, array $params = [], $types = []); | |||
public function executeQuery(string $sql, array $params = [], $types = []): IResult; | |||
/** | |||
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters | |||
@@ -96,12 +101,12 @@ interface IDBConnection { | |||
* @param string $sql The SQL query. | |||
* @param array $params The query parameters. | |||
* @param array $types The parameter types. | |||
* @return integer The number of affected rows. | |||
* @return int The number of affected rows. | |||
* @since 8.0.0 | |||
* | |||
* @deprecated 21.0.0 use executeStatement | |||
*/ | |||
public function executeUpdate($sql, array $params = [], array $types = []); | |||
public function executeUpdate(string $sql, array $params = [], array $types = []): int; | |||
/** | |||
* Executes an SQL INSERT/UPDATE/DELETE query with the given parameters | |||
@@ -112,18 +117,20 @@ interface IDBConnection { | |||
* @param string $sql The SQL query. | |||
* @param array $params The query parameters. | |||
* @param array $types The parameter types. | |||
* @return integer The number of affected rows. | |||
* @return int The number of affected rows. | |||
* @since 21.0.0 | |||
*/ | |||
public function executeStatement($sql, array $params = [], array $types = []); | |||
public function executeStatement($sql, array $params = [], array $types = []): int; | |||
/** | |||
* Used to get the id of the just inserted element | |||
* @param string $table the name of the table where we inserted the item | |||
* @return int the id of the inserted element | |||
* @since 6.0.0 | |||
* @throws Exception since 21.0.0 | |||
* @deprecated 21.0.0 use \OCP\DB\QueryBuilder\IQueryBuilder::getLastInsertId | |||
*/ | |||
public function lastInsertId($table = null); | |||
public function lastInsertId(string $table): int; | |||
/** | |||
* Insert a row if the matching row does not exists. To accomplish proper race condition avoidance | |||
@@ -136,11 +143,11 @@ interface IDBConnection { | |||
* If this is null or an empty array, all keys of $input will be compared | |||
* Please note: text fields (clob) must not be used in the compare array | |||
* @return int number of inserted rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws Exception | |||
* @since 6.0.0 - parameter $compare was added in 8.1.0, return type changed from boolean in 8.1.0 | |||
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371 | |||
*/ | |||
public function insertIfNotExist($table, $input, array $compare = null); | |||
public function insertIfNotExist(string $table, array $input, array $compare = null); | |||
/** | |||
@@ -164,11 +171,11 @@ interface IDBConnection { | |||
* @param array $values (column name => value) | |||
* @param array $updatePreconditionValues ensure values match preconditions (column name => value) | |||
* @return int number of new rows | |||
* @throws \Doctrine\DBAL\DBALException | |||
* @throws Exception | |||
* @throws PreconditionNotMetException | |||
* @since 9.0.0 | |||
*/ | |||
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []); | |||
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int; | |||
/** | |||
* Create an exclusive read+write lock on a table | |||
@@ -180,20 +187,21 @@ interface IDBConnection { | |||
* @param string $tableName | |||
* @since 9.1.0 | |||
*/ | |||
public function lockTable($tableName); | |||
public function lockTable($tableName): void; | |||
/** | |||
* Release a previous acquired lock again | |||
* | |||
* @since 9.1.0 | |||
*/ | |||
public function unlockTable(); | |||
public function unlockTable(): void; | |||
/** | |||
* Start a transaction | |||
* @since 6.0.0 | |||
* @throws Exception since 21.0.0 | |||
*/ | |||
public function beginTransaction(); | |||
public function beginTransaction(): void; | |||
/** | |||
* Check if a transaction is active | |||
@@ -201,32 +209,36 @@ interface IDBConnection { | |||
* @return bool | |||
* @since 8.2.0 | |||
*/ | |||
public function inTransaction(); | |||
public function inTransaction(): bool; | |||
/** | |||
* Commit the database changes done during a transaction that is in progress | |||
* @since 6.0.0 | |||
* @throws Exception since 21.0.0 | |||
*/ | |||
public function commit(); | |||
public function commit(): void; | |||
/** | |||
* Rollback the database changes done during a transaction that is in progress | |||
* @since 6.0.0 | |||
* @throws Exception since 21.0.0 | |||
*/ | |||
public function rollBack(); | |||
public function rollBack(): void; | |||
/** | |||
* Gets the error code and message as a string for logging | |||
* @return string | |||
* @since 6.0.0 | |||
* @deprecated 21.0.0 doesn't return anything meaningful | |||
*/ | |||
public function getError(); | |||
public function getError(): string; | |||
/** | |||
* Fetch the SQLSTATE associated with the last database operation. | |||
* | |||
* @return integer The last error code. | |||
* @since 8.0.0 | |||
* @deprecated 21.0.0 doesn't return anything anymore | |||
*/ | |||
public function errorCode(); | |||
@@ -235,6 +247,7 @@ interface IDBConnection { | |||
* | |||
* @return array The last error information. | |||
* @since 8.0.0 | |||
* @deprecated 21.0.0 doesn't return anything anymore | |||
*/ | |||
public function errorInfo(); | |||
@@ -244,20 +257,20 @@ interface IDBConnection { | |||
* @return bool | |||
* @since 8.0.0 | |||
*/ | |||
public function connect(); | |||
public function connect(): bool; | |||
/** | |||
* Close the database connection | |||
* @since 8.0.0 | |||
*/ | |||
public function close(); | |||
public function close(): void; | |||
/** | |||
* Quotes a given input parameter. | |||
* | |||
* @param mixed $input Parameter to be quoted. | |||
* @param int $type Type of the parameter. | |||
* @return string The quoted parameter. | |||
* @return mixed The quoted parameter. | |||
* @since 8.0.0 | |||
*/ | |||
public function quote($input, $type = IQueryBuilder::PARAM_STR); | |||
@@ -277,7 +290,7 @@ interface IDBConnection { | |||
* @param string $table table name without the prefix | |||
* @since 8.0.0 | |||
*/ | |||
public function dropTable($table); | |||
public function dropTable(string $table): void; | |||
/** | |||
* Check if a table exists | |||
@@ -286,7 +299,7 @@ interface IDBConnection { | |||
* @return bool | |||
* @since 8.0.0 | |||
*/ | |||
public function tableExists($table); | |||
public function tableExists(string $table): bool; | |||
/** | |||
* Escape a parameter to be used in a LIKE query | |||
@@ -295,7 +308,7 @@ interface IDBConnection { | |||
* @return string | |||
* @since 9.0.0 | |||
*/ | |||
public function escapeLikeParameter($param); | |||
public function escapeLikeParameter(string $param): string; | |||
/** | |||
* Check whether or not the current database support 4byte wide unicode | |||
@@ -303,7 +316,7 @@ interface IDBConnection { | |||
* @return bool | |||
* @since 11.0.0 | |||
*/ | |||
public function supports4ByteText(); | |||
public function supports4ByteText(): bool; | |||
/** | |||
* Create the schema of the connected database | |||
@@ -311,7 +324,7 @@ interface IDBConnection { | |||
* @return Schema | |||
* @since 13.0.0 | |||
*/ | |||
public function createSchema(); | |||
public function createSchema(): Schema; | |||
/** | |||
* Migrate the database to the given schema | |||
@@ -319,5 +332,5 @@ interface IDBConnection { | |||
* @param Schema $toSchema | |||
* @since 13.0.0 | |||
*/ | |||
public function migrateToSchema(Schema $toSchema); | |||
public function migrateToSchema(Schema $toSchema): void; | |||
} |
@@ -10,6 +10,7 @@ | |||
namespace Test; | |||
use OC\AppConfig; | |||
use OC\DB\Connection; | |||
use OCP\IConfig; | |||
/** | |||
@@ -23,7 +24,7 @@ class AppConfigTest extends TestCase { | |||
/** @var \OCP\IAppConfig */ | |||
protected $appConfig; | |||
/** @var \OCP\IDBConnection */ | |||
/** @var Connection */ | |||
protected $connection; | |||
protected $originalConfig; | |||
@@ -31,7 +32,7 @@ class AppConfigTest extends TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->connection = \OC::$server->get(Connection::class); | |||
$sql = $this->connection->getQueryBuilder(); | |||
$sql->select('*') | |||
->from('appconfig'); | |||
@@ -138,7 +139,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testGetApps() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertEqualsCanonicalizing([ | |||
'anotherapp', | |||
@@ -149,7 +150,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testGetKeys() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$keys = $config->getKeys('testapp'); | |||
$this->assertEqualsCanonicalizing([ | |||
@@ -162,7 +163,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testGetValue() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$value = $config->getValue('testapp', 'installed_version'); | |||
$this->assertConfigKey('testapp', 'installed_version', $value); | |||
@@ -175,7 +176,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testHasKey() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertTrue($config->hasKey('testapp', 'installed_version')); | |||
$this->assertFalse($config->hasKey('testapp', 'nonexistant')); | |||
@@ -183,13 +184,13 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testSetValueUpdate() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertEquals('1.2.3', $config->getValue('testapp', 'installed_version')); | |||
$this->assertConfigKey('testapp', 'installed_version', '1.2.3'); | |||
$wasModified = $config->setValue('testapp', 'installed_version', '1.2.3'); | |||
if (!(\OC::$server->getDatabaseConnection() instanceof \OC\DB\OracleConnection)) { | |||
if (!(\OC::$server->get(Connection::class) instanceof \OC\DB\OracleConnection)) { | |||
$this->assertFalse($wasModified); | |||
} | |||
@@ -207,7 +208,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testSetValueInsert() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertFalse($config->hasKey('someapp', 'somekey')); | |||
$this->assertNull($config->getValue('someapp', 'somekey')); | |||
@@ -219,13 +220,13 @@ class AppConfigTest extends TestCase { | |||
$this->assertConfigKey('someapp', 'somekey', 'somevalue'); | |||
$wasInserted = $config->setValue('someapp', 'somekey', 'somevalue'); | |||
if (!(\OC::$server->getDatabaseConnection() instanceof \OC\DB\OracleConnection)) { | |||
if (!(\OC::$server->get(Connection::class) instanceof \OC\DB\OracleConnection)) { | |||
$this->assertFalse($wasInserted); | |||
} | |||
} | |||
public function testDeleteKey() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertTrue($config->hasKey('testapp', 'deletethis')); | |||
@@ -247,7 +248,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testDeleteApp() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertTrue($config->hasKey('someapp', 'otherkey')); | |||
@@ -267,7 +268,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testGetValuesNotAllowed() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$this->assertFalse($config->getValues('testapp', 'enabled')); | |||
@@ -275,7 +276,7 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testGetValues() { | |||
$config = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$config = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$sql = \OC::$server->getDatabaseConnection()->getQueryBuilder(); | |||
$sql->select(['configkey', 'configvalue']) | |||
@@ -311,7 +312,7 @@ class AppConfigTest extends TestCase { | |||
public function testGetFilteredValues() { | |||
/** @var \OC\AppConfig|\PHPUnit\Framework\MockObject\MockObject $config */ | |||
$config = $this->getMockBuilder(\OC\AppConfig::class) | |||
->setConstructorArgs([\OC::$server->getDatabaseConnection()]) | |||
->setConstructorArgs([\OC::$server->get(Connection::class)]) | |||
->setMethods(['getValues']) | |||
->getMock(); | |||
@@ -333,8 +334,8 @@ class AppConfigTest extends TestCase { | |||
} | |||
public function testSettingConfigParallel() { | |||
$appConfig1 = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$appConfig2 = new \OC\AppConfig(\OC::$server->getDatabaseConnection()); | |||
$appConfig1 = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$appConfig2 = new \OC\AppConfig(\OC::$server->get(Connection::class)); | |||
$appConfig1->getValue('testapp', 'foo', 'v1'); | |||
$appConfig2->getValue('testapp', 'foo', 'v1'); | |||
@@ -23,12 +23,15 @@ | |||
namespace Test\AppFramework\Db; | |||
use OCP\DB\IPreparedStatement; | |||
use OCP\DB\IResult; | |||
/** | |||
* Simple utility class for testing mappers | |||
*/ | |||
abstract class MapperTestUtility extends \Test\TestCase { | |||
protected $db; | |||
private $query; | |||
private $statement; | |||
private $queryAt; | |||
private $prepareAt; | |||
private $fetchAt; | |||
@@ -47,7 +50,7 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$this->query = $this->createMock('\PDOStatement'); | |||
$this->statement = $this->createMock(IPreparedStatement::class); | |||
$this->queryAt = 0; | |||
$this->prepareAt = 0; | |||
$this->iterators = []; | |||
@@ -94,26 +97,26 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
$this->db->expects($this->at($this->prepareAt)) | |||
->method('prepare') | |||
->with($this->equalTo($sql)) | |||
->will(($this->returnValue($this->query))); | |||
->will(($this->returnValue($this->statement))); | |||
} elseif ($limit !== null && $offset === null) { | |||
$this->db->expects($this->at($this->prepareAt)) | |||
->method('prepare') | |||
->with($this->equalTo($sql), $this->equalTo($limit)) | |||
->will(($this->returnValue($this->query))); | |||
->will(($this->returnValue($this->statement))); | |||
} elseif ($limit === null && $offset !== null) { | |||
$this->db->expects($this->at($this->prepareAt)) | |||
->method('prepare') | |||
->with($this->equalTo($sql), | |||
$this->equalTo(null), | |||
$this->equalTo($offset)) | |||
->will(($this->returnValue($this->query))); | |||
->will(($this->returnValue($this->statement))); | |||
} else { | |||
$this->db->expects($this->at($this->prepareAt)) | |||
->method('prepare') | |||
->with($this->equalTo($sql), | |||
$this->equalTo($limit), | |||
$this->equalTo($offset)) | |||
->will(($this->returnValue($this->query))); | |||
->will(($this->returnValue($this->statement))); | |||
} | |||
$this->iterators[] = new ArgumentIterator($returnRows); | |||
@@ -121,7 +124,7 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
$iterators = $this->iterators; | |||
$fetchAt = $this->fetchAt; | |||
$this->query->expects($this->any()) | |||
$this->statement->expects($this->any()) | |||
->method('fetch') | |||
->willReturnCallback( | |||
function () use ($iterators, $fetchAt) { | |||
@@ -141,7 +144,7 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
if ($this->isAssocArray($arguments)) { | |||
foreach ($arguments as $key => $argument) { | |||
$pdoConstant = $this->getPDOType($argument); | |||
$this->query->expects($this->at($this->queryAt)) | |||
$this->statement->expects($this->at($this->queryAt)) | |||
->method('bindValue') | |||
->with($this->equalTo($key), | |||
$this->equalTo($argument), | |||
@@ -152,7 +155,7 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
$index = 1; | |||
foreach ($arguments as $argument) { | |||
$pdoConstant = $this->getPDOType($argument); | |||
$this->query->expects($this->at($this->queryAt)) | |||
$this->statement->expects($this->at($this->queryAt)) | |||
->method('bindValue') | |||
->with($this->equalTo($index), | |||
$this->equalTo($argument), | |||
@@ -162,9 +165,10 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
} | |||
} | |||
$this->query->expects($this->at($this->queryAt)) | |||
$this->statement->expects($this->at($this->queryAt)) | |||
->method('execute') | |||
->willReturnCallback(function ($sql, $p = null, $o = null, $s = null) { | |||
return $this->createMock(IResult::class); | |||
}); | |||
$this->queryAt++; | |||
@@ -175,7 +179,7 @@ abstract class MapperTestUtility extends \Test\TestCase { | |||
} else { | |||
$closing = $this->any(); | |||
} | |||
$this->query->expects($closing)->method('closeCursor'); | |||
$this->statement->expects($closing)->method('closeCursor'); | |||
$this->queryAt++; | |||
$this->prepareAt++; |
@@ -44,7 +44,7 @@ class ConnectionTest extends \Test\TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->connection = \OC::$server->get(\OC\DB\Connection::class); | |||
} | |||
protected function tearDown(): void { | |||
@@ -234,7 +234,7 @@ class ConnectionTest extends \Test\TestCase { | |||
$query = $this->connection->prepare('SELECT * FROM `*PREFIX*table`'); | |||
$result = $query->execute(); | |||
$this->assertTrue((bool)$result); | |||
$this->assertEquals(7, count($query->fetchAll())); | |||
$this->assertEquals(7, count($result->fetchAll())); | |||
} | |||
public function testInsertIfNotExistNull() { | |||
@@ -263,7 +263,7 @@ class ConnectionTest extends \Test\TestCase { | |||
$query = $this->connection->prepare('SELECT * FROM `*PREFIX*table`'); | |||
$result = $query->execute(); | |||
$this->assertTrue((bool)$result); | |||
$this->assertEquals(2, count($query->fetchAll())); | |||
$this->assertEquals(2, count($result->fetchAll())); | |||
} | |||
public function testInsertIfNotExistDonTOverwrite() { | |||
@@ -278,11 +278,10 @@ class ConnectionTest extends \Test\TestCase { | |||
// Normal test to have same known data inserted. | |||
$query = $this->connection->prepare('INSERT INTO `*PREFIX*table` (`textfield`, `clobfield`) VALUES (?, ?)'); | |||
$result = $query->execute([$fullName, $uri]); | |||
$this->assertEquals(1, $result); | |||
$this->assertEquals(1, $result->rowCount()); | |||
$query = $this->connection->prepare('SELECT `textfield`, `clobfield` FROM `*PREFIX*table` WHERE `clobfield` = ?'); | |||
$result = $query->execute([$uri]); | |||
$this->assertTrue($result); | |||
$rowset = $query->fetchAll(); | |||
$rowset = $result->fetchAll(); | |||
$this->assertEquals(1, count($rowset)); | |||
$this->assertArrayHasKey('textfield', $rowset[0]); | |||
$this->assertEquals($fullName, $rowset[0]['textfield']); | |||
@@ -297,10 +296,9 @@ class ConnectionTest extends \Test\TestCase { | |||
$query = $this->connection->prepare('SELECT `textfield`, `clobfield` FROM `*PREFIX*table` WHERE `clobfield` = ?'); | |||
$result = $query->execute([$uri]); | |||
$this->assertTrue($result); | |||
// Test that previously inserted data isn't overwritten | |||
// And that a new row hasn't been inserted. | |||
$rowset = $query->fetchAll(); | |||
$rowset = $result->fetchAll(); | |||
$this->assertEquals(1, count($rowset)); | |||
$this->assertArrayHasKey('textfield', $rowset[0]); | |||
$this->assertEquals($fullName, $rowset[0]['textfield']); |
@@ -64,7 +64,6 @@ class DBSchemaTest extends TestCase { | |||
public function testSchema() { | |||
$this->doTestSchemaCreating(); | |||
$this->doTestSchemaChanging(); | |||
$this->doTestSchemaDumping(); | |||
$this->doTestSchemaRemoving(); | |||
} | |||
@@ -79,14 +78,6 @@ class DBSchemaTest extends TestCase { | |||
$this->assertTableExist($this->table2); | |||
} | |||
public function doTestSchemaDumping() { | |||
$outfile = $this->tempManager->getTemporaryFile(); | |||
OC_DB::getDbStructure($outfile); | |||
$content = file_get_contents($outfile); | |||
$this->assertStringContainsString($this->table1, $content); | |||
$this->assertStringContainsString($this->table2, $content); | |||
} | |||
public function doTestSchemaRemoving() { | |||
OC_DB::removeDBStructure($this->schema_file); | |||
$this->assertTableNotExist($this->table1); |
@@ -30,7 +30,7 @@ class MDB2SchemaManagerTest extends \Test\TestCase { | |||
} | |||
public function testAutoIncrement() { | |||
$connection = \OC::$server->getDatabaseConnection(); | |||
$connection = \OC::$server->get(\OC\DB\Connection::class); | |||
if ($connection->getDatabasePlatform() instanceof OraclePlatform) { | |||
$this->markTestSkipped('Adding auto increment columns in Oracle is not supported.'); | |||
} |
@@ -9,7 +9,7 @@ | |||
namespace Test\DB; | |||
use Doctrine\DBAL\Platforms\MySqlPlatform; | |||
use Doctrine\DBAL\Platforms\MySQLPlatform; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use OC\DB\MDB2SchemaReader; | |||
use OCP\IConfig; | |||
@@ -50,7 +50,7 @@ class MDB2SchemaReaderTest extends TestCase { | |||
} | |||
public function testRead() { | |||
$reader = new MDB2SchemaReader($this->getConfig(), new MySqlPlatform()); | |||
$reader = new MDB2SchemaReader($this->getConfig(), new MySQLPlatform()); | |||
$schema = $reader->loadSchemaFromFile(__DIR__ . '/testschema.xml', new Schema()); | |||
$this->assertCount(1, $schema->getTables()); | |||
@@ -9,7 +9,7 @@ | |||
namespace Test\DB; | |||
use Doctrine\DBAL\DBALException; | |||
use Doctrine\DBAL\Exception; | |||
use Doctrine\DBAL\Platforms\OraclePlatform; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use Doctrine\DBAL\Schema\SchemaConfig; | |||
@@ -49,7 +49,7 @@ class MigratorTest extends \Test\TestCase { | |||
parent::setUp(); | |||
$this->config = \OC::$server->getConfig(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->connection = \OC::$server->get(\OC\DB\Connection::class); | |||
if ($this->connection->getDatabasePlatform() instanceof OraclePlatform) { | |||
$this->markTestSkipped('DB migration tests are not supported on OCI'); | |||
} | |||
@@ -66,12 +66,12 @@ class MigratorTest extends \Test\TestCase { | |||
// Try to delete if exists (IF EXISTS NOT SUPPORTED IN ORACLE) | |||
try { | |||
$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableNameTmp)); | |||
} catch (\Doctrine\DBAL\DBALException $e) { | |||
} catch (Exception $e) { | |||
} | |||
try { | |||
$this->connection->exec('DROP TABLE ' . $this->connection->quoteIdentifier($this->tableName)); | |||
} catch (\Doctrine\DBAL\DBALException $e) { | |||
} catch (Exception $e) { | |||
} | |||
parent::tearDown(); | |||
} | |||
@@ -125,9 +125,9 @@ class MigratorTest extends \Test\TestCase { | |||
return $this->connection->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver; | |||
} | |||
public function testDuplicateKeyUpgrade() { | |||
$this->expectException(\OC\DB\MigrationException::class); | |||
$this->expectException(Exception\UniqueConstraintViolationException::class); | |||
if ($this->isSQLite()) { | |||
$this->markTestSkipped('sqlite does not throw errors when creating a new key on existing data'); | |||
@@ -140,8 +140,12 @@ class MigratorTest extends \Test\TestCase { | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'bar']); | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'qwerty']); | |||
$migrator->checkMigrate($endSchema); | |||
$this->fail('checkMigrate should have failed'); | |||
try { | |||
$migrator->migrate($endSchema); | |||
} catch (Exception\UniqueConstraintViolationException $e) { | |||
$this->connection->rollBack(); | |||
throw $e; | |||
} | |||
} | |||
public function testChangeToString() { | |||
@@ -156,7 +160,6 @@ class MigratorTest extends \Test\TestCase { | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'bar']); | |||
$this->connection->insert($this->tableName, ['id' => 3, 'name' => 'qwerty']); | |||
$migrator->checkMigrate($endSchema); | |||
$migrator->migrate($endSchema); | |||
$this->addToAssertionCount(1); | |||
@@ -181,7 +184,6 @@ class MigratorTest extends \Test\TestCase { | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'bar']); | |||
$this->connection->insert($this->tableName, ['id' => 3, 'name' => 'qwerty']); | |||
$migrator->checkMigrate($endSchema); | |||
$migrator->migrate($endSchema); | |||
$this->addToAssertionCount(1); | |||
} | |||
@@ -200,7 +202,6 @@ class MigratorTest extends \Test\TestCase { | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'bar']); | |||
$this->connection->insert($this->tableName, ['id' => 3, 'name' => 'qwerty']); | |||
$migrator->checkMigrate($endSchema); | |||
$migrator->migrate($endSchema); | |||
$this->addToAssertionCount(1); | |||
@@ -219,7 +220,7 @@ class MigratorTest extends \Test\TestCase { | |||
try { | |||
$this->connection->insert($this->tableName, ['id' => 2, 'name' => 'qwerty']); | |||
$this->fail('Expected duplicate key insert to fail'); | |||
} catch (DBALException $e) { | |||
} catch (Exception $e) { | |||
$this->addToAssertionCount(1); | |||
} | |||
} | |||
@@ -239,7 +240,6 @@ class MigratorTest extends \Test\TestCase { | |||
$migrator = $this->manager->getMigrator(); | |||
$migrator->migrate($startSchema); | |||
$migrator->checkMigrate($endSchema); | |||
$migrator->migrate($endSchema); | |||
$this->addToAssertionCount(1); | |||
@@ -261,7 +261,6 @@ class MigratorTest extends \Test\TestCase { | |||
$migrator = $this->manager->getMigrator(); | |||
$migrator->migrate($startSchema); | |||
$migrator->checkMigrate($endSchema); | |||
$migrator->migrate($endSchema); | |||
$this->addToAssertionCount(1); |
@@ -24,7 +24,7 @@ class MySqlMigrationTest extends \Test\TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->connection = \OC::$server->get(\OC\DB\Connection::class); | |||
if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) { | |||
$this->markTestSkipped("Test only relevant on MySql"); | |||
} |
@@ -21,7 +21,7 @@ | |||
namespace Test\DB; | |||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform; | |||
use Doctrine\DBAL\Platforms\PostgreSQL100Platform; | |||
use Doctrine\DBAL\Schema\Comparator; | |||
use Doctrine\DBAL\Schema\Schema; | |||
use Doctrine\DBAL\Types\Types; | |||
@@ -38,7 +38,7 @@ use Doctrine\DBAL\Types\Types; | |||
*/ | |||
class OCPostgreSqlPlatformTest extends \Test\TestCase { | |||
public function testAlterBigint() { | |||
$platform = new PostgreSqlPlatform(); | |||
$platform = new PostgreSQL100Platform(); | |||
$sourceSchema = new Schema(); | |||
$targetSchema = new Schema(); | |||
@@ -68,7 +68,7 @@ class ExpressionBuilderDBTest extends TestCase { | |||
->where($query->expr()->like($query->createNamedParameter($param1), $query->createNamedParameter($param2))); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals($match, $column); | |||
} | |||
@@ -105,7 +105,7 @@ class ExpressionBuilderDBTest extends TestCase { | |||
->where($query->expr()->iLike($query->createNamedParameter($param1), $query->createNamedParameter($param2))); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals($match, $column); | |||
} |
@@ -40,19 +40,23 @@ class ExpressionBuilderTest extends TestCase { | |||
/** @var DoctrineExpressionBuilder */ | |||
protected $doctrineExpressionBuilder; | |||
/** @var \Doctrine\DBAL\Connection|\OCP\IDBConnection */ | |||
/** @var \OCP\IDBConnection */ | |||
protected $connection; | |||
/** @var \Doctrine\DBAL\Connection */ | |||
protected $internalConnection; | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->internalConnection = \OC::$server->get(\OC\DB\Connection::class); | |||
$queryBuilder = $this->createMock(IQueryBuilder::class); | |||
$this->expressionBuilder = new ExpressionBuilder($this->connection, $queryBuilder); | |||
$this->doctrineExpressionBuilder = new DoctrineExpressionBuilder($this->connection); | |||
$this->doctrineExpressionBuilder = new DoctrineExpressionBuilder($this->internalConnection); | |||
} | |||
public function dataComparison() { |
@@ -49,7 +49,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals('foobar', $column); | |||
} | |||
@@ -62,7 +62,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(md5('foobar'), $column); | |||
} | |||
@@ -75,7 +75,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals('oo', $column); | |||
} | |||
@@ -88,7 +88,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals('oobar', $column); | |||
} | |||
@@ -101,7 +101,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals('foobar', $column); | |||
} | |||
@@ -114,7 +114,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(3, $column); | |||
} | |||
@@ -127,7 +127,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(1, $column); | |||
} | |||
@@ -140,7 +140,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$column = $result->fetchColumn(); | |||
$column = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertGreaterThan(1, $column); | |||
} | |||
@@ -176,7 +176,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(null, $row); | |||
} | |||
@@ -192,7 +192,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(null, $row); | |||
} | |||
@@ -211,7 +211,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(20, $row); | |||
} | |||
@@ -230,7 +230,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(10, $row); | |||
} | |||
@@ -243,7 +243,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(2, $row); | |||
} | |||
@@ -256,7 +256,7 @@ class FunctionBuilderTest extends TestCase { | |||
->setMaxResults(1); | |||
$result = $query->execute(); | |||
$row = $result->fetchColumn(); | |||
$row = $result->fetchOne(); | |||
$result->closeCursor(); | |||
$this->assertEquals(1, $row); | |||
} |
@@ -26,6 +26,7 @@ use Doctrine\DBAL\Schema\SchemaDiff; | |||
use OC\DB\MDB2SchemaManager; | |||
use OC\DB\MDB2SchemaReader; | |||
use OCP\IConfig; | |||
use OCP\IDBConnection; | |||
use Test\TestCase; | |||
/** | |||
@@ -36,8 +37,10 @@ use Test\TestCase; | |||
* @package Test\DB | |||
*/ | |||
class SchemaDiffTest extends TestCase { | |||
/** @var \Doctrine\DBAL\Connection $connection */ | |||
/** @var IDBConnection $connection */ | |||
private $connection; | |||
/** @var \Doctrine\DBAL\Connection $connection */ | |||
private $internalConnection; | |||
/** @var MDB2SchemaManager */ | |||
private $manager; | |||
@@ -57,7 +60,8 @@ class SchemaDiffTest extends TestCase { | |||
$this->config = \OC::$server->getConfig(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->manager = new MDB2SchemaManager($this->connection); | |||
$this->internalConnection = \OC::$server->get(\OC\DB\Connection::class); | |||
$this->manager = new MDB2SchemaManager($this->internalConnection); | |||
$this->testPrefix = strtolower($this->getUniqueID($this->config->getSystemValue('dbtableprefix', 'oc_'), 3)); | |||
} | |||
@@ -79,17 +83,17 @@ class SchemaDiffTest extends TestCase { | |||
$this->manager->createDbFromStructure($schemaFile); | |||
$schemaReader = new MDB2SchemaReader($this->config, $this->connection->getDatabasePlatform()); | |||
$toSchema = new Schema([], [], $this->connection->getSchemaManager()->createSchemaConfig()); | |||
$toSchema = new Schema([], [], $this->internalConnection->getSchemaManager()->createSchemaConfig()); | |||
$endSchema = $schemaReader->loadSchemaFromFile($schemaFile, $toSchema); | |||
// get the diff | |||
/** @var SchemaDiff $diff */ | |||
$migrator = $this->manager->getMigrator(); | |||
$diff = $this->invokePrivate($migrator, 'getDiff', [$endSchema, $this->connection]); | |||
$diff = $this->invokePrivate($migrator, 'getDiff', [$endSchema, $this->internalConnection]); | |||
// no sql statement is expected | |||
$sqls = $diff->toSql($this->connection->getDatabasePlatform()); | |||
$this->assertEquals([], $sqls); | |||
$this->assertEmpty($sqls); | |||
} | |||
public function providesSchemaFiles() { |
@@ -24,14 +24,14 @@ class SqliteMigrationTest extends \Test\TestCase { | |||
protected function setUp(): void { | |||
parent::setUp(); | |||
$this->connection = \OC::$server->getDatabaseConnection(); | |||
$this->connection = \OC::$server->get(\OC\DB\Connection::class); | |||
if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { | |||
$this->markTestSkipped("Test only relevant on Sqlite"); | |||
} | |||
$dbPrefix = \OC::$server->getConfig()->getSystemValue("dbtableprefix"); | |||
$this->tableName = $this->getUniqueID($dbPrefix . '_enum_bit_test'); | |||
$this->connection->exec("CREATE TABLE $this->tableName(t0 tinyint unsigned, t1 tinyint)"); | |||
$this->connection->prepare("CREATE TABLE $this->tableName(t0 tinyint unsigned, t1 tinyint)")->execute(); | |||
} | |||
protected function tearDown(): void { |
@@ -116,7 +116,7 @@ class CacheTest extends \Test\TestCase { | |||
public function testFolder($folder) { | |||
if (strpos($folder, 'F09F9890')) { | |||
// 4 byte UTF doesn't work on mysql | |||
$params = \OC::$server->getDatabaseConnection()->getParams(); | |||
$params = \OC::$server->get(\OC\DB\Connection::class)->getParams(); | |||
if (\OC::$server->getDatabaseConnection()->getDatabasePlatform() instanceof MySqlPlatform && $params['charset'] !== 'utf8mb4') { | |||
$this->markTestSkipped('MySQL doesn\'t support 4 byte UTF-8'); | |||
} |