Signed-off-by: Joas Schilling <coding@schilljs.com>tags/v16.0.0alpha1
@@ -0,0 +1,76 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Core\Migrations; | |||
use Closure; | |||
use Doctrine\DBAL\Types\Type; | |||
use OCP\DB\ISchemaWrapper; | |||
use OCP\Migration\SimpleMigrationStep; | |||
use OCP\Migration\IOutput; | |||
class Version15000Date20180917092725 extends SimpleMigrationStep { | |||
/** | |||
* @param IOutput $output | |||
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` | |||
* @param array $options | |||
* @return null|ISchemaWrapper | |||
*/ | |||
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { | |||
/** @var ISchemaWrapper $schema */ | |||
$schema = $schemaClosure(); | |||
if (!$schema->hasTable('collres_collections')) { | |||
$table = $schema->createTable('collres_collections'); | |||
$table->addColumn('id', Type::BIGINT, [ | |||
'autoincrement' => true, | |||
'notnull' => true, | |||
]); | |||
$table->setPrimaryKey(['id']); | |||
} | |||
if (!$schema->hasTable('collres_resources')) { | |||
$table = $schema->createTable('collres_resources'); | |||
$table->addColumn('collection_id', Type::BIGINT, [ | |||
'notnull' => true, | |||
]); | |||
$table->addColumn('resource_type', Type::STRING, [ | |||
'notnull' => true, | |||
'length' => 64, | |||
]); | |||
$table->addColumn('resource_id', Type::STRING, [ | |||
'notnull' => true, | |||
'length' => 64, | |||
]); | |||
$table->addUniqueIndex(['collection_id', 'resource_type', 'resource_id'], 'collres_unique_res'); | |||
} | |||
return $schema; | |||
} | |||
} |
@@ -0,0 +1,155 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
use Doctrine\DBAL\Exception\ConstraintViolationException; | |||
use OCP\Collaboration\Resources\IManager; | |||
use OCP\Collaboration\Resources\ResourceException; | |||
use OCP\Collaboration\Resources\ICollection; | |||
use OCP\Collaboration\Resources\IResource; | |||
use OCP\DB\QueryBuilder\IQueryBuilder; | |||
use OCP\IDBConnection; | |||
class Collection implements ICollection { | |||
/** @var IManager */ | |||
protected $manager; | |||
/** @var IDBConnection */ | |||
protected $connection; | |||
/** @var int */ | |||
protected $id; | |||
/** @var IResource[] */ | |||
protected $resources; | |||
public function __construct(IManager $manager, IDBConnection $connection, int $id) { | |||
$this->manager = $manager; | |||
$this->connection = $connection; | |||
$this->id = $id; | |||
$this->resources = []; | |||
} | |||
/** | |||
* @return IResource[] | |||
* @since 15.0.0 | |||
*/ | |||
public function getResources(): array { | |||
if (empty($this->resources)) { | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->select('resource_type', 'resource_id') | |||
->from('collres_resources') | |||
->where($query->expr()->eq('collection_id', $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT))); | |||
$result = $query->execute(); | |||
while ($row = $result->fetch()) { | |||
$this->resources[] = $this->manager->getResource($row['resource_type'], $row['resource_id']); | |||
} | |||
$result->closeCursor(); | |||
} | |||
return $this->resources; | |||
} | |||
/** | |||
* Adds a resource to a collection | |||
* | |||
* @param IResource $resource | |||
* @throws ResourceException when the resource is already part of the collection | |||
* @since 15.0.0 | |||
*/ | |||
public function addResource(IResource $resource) { | |||
array_map(function(IResource $r) use ($resource) { | |||
if ($this->isSameResource($r, $resource)) { | |||
throw new ResourceException('Already part of the collection'); | |||
} | |||
}, $this->resources); | |||
$this->resources[] = $resource; | |||
if ($this->id === 0) { | |||
$this->makeCollectionPersistent(); | |||
} | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->insert('collres_resources') | |||
->values([ | |||
'collection_id' => $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT), | |||
'resource_type' => $query->createNamedParameter($resource->getType()), | |||
'resource_id' => $query->createNamedParameter($resource->getId()), | |||
]); | |||
try { | |||
$query->execute(); | |||
} catch (ConstraintViolationException $e) { | |||
throw new ResourceException('Already part of the collection'); | |||
} | |||
} | |||
/** | |||
* Removes a resource from a collection | |||
* | |||
* @param IResource $resource | |||
* @since 15.0.0 | |||
*/ | |||
public function removeResource(IResource $resource) { | |||
$this->resources = array_filter($this->resources, function(IResource $r) use ($resource) { | |||
return !$this->isSameResource($r, $resource); | |||
}); | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->delete('collres_resources') | |||
->where($query->expr()->eq('collection_id', $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT))) | |||
->andWhere($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType()))) | |||
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId()))); | |||
$query->execute(); | |||
if (empty($this->resources)) { | |||
$this->makeCollectionUnsteady(); | |||
} | |||
} | |||
protected function isSameResource(IResource $resource1, IResource $resource2): bool { | |||
return $resource1->getType() === $resource2->getType() && | |||
$resource1->getId() === $resource2->getId(); | |||
} | |||
protected function makeCollectionPersistent() { | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->insert('collres_collections'); | |||
$query->execute(); | |||
$this->id = $query->getLastInsertId(); | |||
} | |||
protected function makeCollectionUnsteady() { | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->delete('collres_collections') | |||
->where($query->expr()->eq('id', $query->createNamedParameter($this->id, IQueryBuilder::PARAM_INT))); | |||
$query->execute(); | |||
$this->id = 0; | |||
} | |||
} |
@@ -0,0 +1,58 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
use OCP\Collaboration\Resources\ICollection; | |||
use OCP\Collaboration\Resources\IManager; | |||
use OCP\Collaboration\Resources\IResource; | |||
use OCP\IDBConnection; | |||
class Manager implements IManager { | |||
/** @var IDBConnection */ | |||
protected $connection; | |||
public function __construct(IDBConnection $connection) { | |||
$this->connection = $connection; | |||
} | |||
/** | |||
* @param int $id | |||
* @return ICollection | |||
* @since 15.0.0 | |||
*/ | |||
public function getCollection(int $id): ICollection { | |||
return new Collection($this, $this->connection, $id); | |||
} | |||
/** | |||
* @param string $type | |||
* @param string $id | |||
* @return IResource | |||
* @since 15.0.0 | |||
*/ | |||
public function getResource(string $type, string $id): IResource { | |||
return new Resource($this, $this->connection, $type, $id); | |||
} | |||
} |
@@ -0,0 +1,91 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
use OCP\Collaboration\Resources\ICollection; | |||
use OCP\Collaboration\Resources\IManager; | |||
use OCP\Collaboration\Resources\IResource; | |||
use OCP\IDBConnection; | |||
class Resource implements IResource { | |||
/** @var IManager */ | |||
protected $manager; | |||
/** @var IDBConnection */ | |||
protected $connection; | |||
/** @var string */ | |||
protected $type; | |||
/** @var string */ | |||
protected $id; | |||
public function __construct(IManager $manager, IDBConnection $connection, string $type, string $id) { | |||
$this->manager = $manager; | |||
$this->connection = $connection; | |||
$this->type = $type; | |||
$this->id = $id; | |||
} | |||
/** | |||
* @return string | |||
* @since 15.0.0 | |||
*/ | |||
public function getType(): string { | |||
return $this->type; | |||
} | |||
/** | |||
* @return string | |||
* @since 15.0.0 | |||
*/ | |||
public function getId(): string { | |||
return $this->id; | |||
} | |||
/** | |||
* @param IResource $resource | |||
* @return ICollection[] | |||
* @since 15.0.0 | |||
*/ | |||
public function getCollections(IResource $resource): array { | |||
$collections = []; | |||
$query = $this->connection->getQueryBuilder(); | |||
$query->select('collection_id') | |||
->from('collres_resources') | |||
->where($query->expr()->eq('resource_type', $query->createNamedParameter($resource->getType()))) | |||
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resource->getId()))); | |||
$result = $query->execute(); | |||
while ($row = $result->fetch()) { | |||
$collections[] = $this->manager->getCollection((int) $row['collection_id']); | |||
} | |||
$result->closeCursor(); | |||
return $collections; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
/** | |||
* @since 15.0.0 | |||
*/ | |||
interface ICollection { | |||
/** | |||
* @return IResource[] | |||
* @since 15.0.0 | |||
*/ | |||
public function getResources(): array; | |||
/** | |||
* Adds a resource to a collection | |||
* | |||
* @param IResource $resource | |||
* @throws ResourceException when the resource is already part of the collection | |||
* @since 15.0.0 | |||
*/ | |||
public function addResource(IResource $resource); | |||
/** | |||
* Removes a resource from a collection | |||
* | |||
* @param IResource $resource | |||
* @since 15.0.0 | |||
*/ | |||
public function removeResource(IResource $resource); | |||
} |
@@ -0,0 +1,45 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
/** | |||
* @since 15.0.0 | |||
*/ | |||
interface IManager extends IProvider { | |||
/** | |||
* @param int $id | |||
* @return ICollection | |||
* @since 15.0.0 | |||
*/ | |||
public function getCollection(int $id): ICollection; | |||
/** | |||
* @param string $type | |||
* @param string $id | |||
* @return IResource | |||
* @since 15.0.0 | |||
*/ | |||
public function getResource(string $type, string $id): IResource; | |||
} |
@@ -0,0 +1,27 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
interface IProvider { | |||
} |
@@ -0,0 +1,48 @@ | |||
<?php | |||
declare(strict_types=1); | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
/** | |||
* @since 15.0.0 | |||
*/ | |||
interface IResource { | |||
/** | |||
* @return string | |||
* @since 15.0.0 | |||
*/ | |||
public function getType(): string; | |||
/** | |||
* @return string | |||
* @since 15.0.0 | |||
*/ | |||
public function getId(): string; | |||
/** | |||
* @param IResource $resource | |||
* @return ICollection[] | |||
* @since 15.0.0 | |||
*/ | |||
public function getCollections(IResource $resource): array; | |||
} |
@@ -0,0 +1,27 @@ | |||
<?php | |||
/** | |||
* @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com> | |||
* | |||
* @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\Collaboration\Resources; | |||
class ResourceException extends \RuntimeException { | |||
} |