mirror of https://github.com/nextcloud/bookmarks
Add migration and implement PublicFolderMapper
This commit is contained in:
parent
e323f10c03
commit
9b5b271136
|
@ -44,7 +44,7 @@ class BookmarkMapper extends QBMapper {
|
|||
* @param UrlNormalizer $urlNormalizer
|
||||
*/
|
||||
public function __construct(IDBConnection $db, EventDispatcherInterface $eventDispatcher, UrlNormalizer $urlNormalizer, IConfig $config) {
|
||||
parent::__construct($db, 'bookmarks');
|
||||
parent::__construct($db, 'bookmarks', Bookmark::class);
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
$this->urlNormalizer = $urlNormalizer;
|
||||
$this->config = $config;
|
||||
|
|
|
@ -33,7 +33,7 @@ class FolderMapper extends QBMapper {
|
|||
* @param BookmarkMapper $bookmarkMapper
|
||||
*/
|
||||
public function __construct(IDBConnection $db, BookmarkMapper $bookmarkMapper) {
|
||||
parent::__construct($db, 'bookmarks_folders');
|
||||
parent::__construct($db, 'bookmarks_folders', Folder::class);
|
||||
$this->bookmarkMapper = $bookmarkMapper;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
namespace OCA\Bookmarks\Db;
|
||||
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
|
||||
class PublicFolder extends Entity {
|
||||
protected $folderId;
|
||||
protected $description;
|
||||
protected $createdAt;
|
||||
|
||||
public static $columns = ['id', 'folder_id', 'description', 'created_at'];
|
||||
|
||||
public function __construct() {
|
||||
// add types in constructor
|
||||
$this->addType('id', 'string');
|
||||
$this->addType('folderId', 'integer');
|
||||
$this->addType('description', 'integer');
|
||||
$this->addType('created_at', 'integer');
|
||||
}
|
||||
|
||||
public function setId(string $id) {
|
||||
$this->id = $id;
|
||||
$this->markFieldUpdated('id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
namespace OCA\Bookmarks\Db;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Db\Entity;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\AppFramework\Db\QBMapper;
|
||||
|
||||
/**
|
||||
* Class PublicFolderMapper
|
||||
*
|
||||
* @package OCA\Bookmarks\Db
|
||||
*/
|
||||
class PublicFolderMapper extends QBMapper {
|
||||
|
||||
/**
|
||||
* @var IDBConnection
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* TagMapper constructor.
|
||||
*
|
||||
* @param IDBConnection $db
|
||||
*/
|
||||
public function __construct(IDBConnection $db) {
|
||||
parent::__construct($db, 'bookmarks_folders_public', PublicFolder::class);
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return Entity
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
*/
|
||||
public function find(string $id) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb
|
||||
->select('*')
|
||||
->from('bookmarks_folders_public')
|
||||
->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $folderId
|
||||
* @return Entity
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
*/
|
||||
public function findByFolder(int $folderId) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb
|
||||
->select('*')
|
||||
->from('bookmarks_folders_public')
|
||||
->where($qb->expr()->eq('folder_id', $qb->createNamedParameter($folderId)));
|
||||
|
||||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $createdAt
|
||||
* @return array|Entity[]
|
||||
*/
|
||||
public function findAllCreatedBefore(int $createdAt) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb
|
||||
->select('*')
|
||||
->from('bookmarks_folders_public')
|
||||
->where($qb->expr()->lt('created_at', $qb->createNamedParameter($createdAt)));
|
||||
|
||||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity $publicFolder
|
||||
* @return Entity
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function insert(Entity $publicFolder) : Entity {
|
||||
try{
|
||||
while(true) {
|
||||
$publicFolder->setId(self::randomString(32));
|
||||
$this->find($publicFolder->getId());
|
||||
}
|
||||
} catch(DoesNotExistException $e) {
|
||||
return parent::insert($publicFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity $publicFolder
|
||||
* @return Entity
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
|
||||
*/
|
||||
public function insertOrUpdate(Entity $publicFolder) : Entity {
|
||||
try{
|
||||
$this->find($publicFolder->getId());
|
||||
} catch(DoesNotExistException $e) {
|
||||
return $this->insert($publicFolder);
|
||||
}
|
||||
$this->update($publicFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random string, using a cryptographically secure
|
||||
* pseudorandom number generator (random_int)
|
||||
*
|
||||
* This function uses type hints now (PHP 7+ only), but it was originally
|
||||
* written for PHP 5 as well.
|
||||
*
|
||||
* For PHP 7, random_int is a PHP core function
|
||||
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
|
||||
*
|
||||
* @param int $length How many characters do we want?
|
||||
* @param string $keyspace A string of all possible characters
|
||||
* to select from
|
||||
* @return string
|
||||
* @throws \RangeException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function randomString(
|
||||
int $length = 64,
|
||||
string $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
) : string {
|
||||
if ($length < 1) {
|
||||
throw new \RangeException("Length must be a positive integer");
|
||||
}
|
||||
$pieces = [];
|
||||
$max = mb_strlen($keyspace, '8bit') - 1;
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$pieces []= $keyspace[random_int(0, $max)];
|
||||
}
|
||||
return implode('', $pieces);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
namespace OCA\Bookmarks\Migration;
|
||||
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\IDBConnection;
|
||||
|
||||
/**
|
||||
* Auto-generated migration step: Please modify to your needs!
|
||||
*/
|
||||
class Version003000000Date20191129094721 extends SimpleMigrationStep {
|
||||
private $db;
|
||||
|
||||
public function __construct(IDBConnection $db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
* @param array $options
|
||||
*/
|
||||
public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
* @param array $options
|
||||
* @return null|ISchemaWrapper
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
if (!$schema->hasTable('bookmarks_folders_public')) {
|
||||
$table = $schema->createTable('bookmarks_folders_public');
|
||||
$table->addColumn('id', 'string', [
|
||||
'notnull' => true,
|
||||
'length' => 32,
|
||||
]);
|
||||
$table->addColumn('folder_id', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('description', 'string', [
|
||||
'notnull' => true,
|
||||
'length' => 4096,
|
||||
'default' => '',
|
||||
]);
|
||||
$table->addColumn('created_at', 'integer', [
|
||||
'notnull' => false,
|
||||
'length' => 4,
|
||||
'default' => 0,
|
||||
'unsigned' => true,
|
||||
]);
|
||||
$table->setPrimaryKey(['id'], 'bookmarks_public_id');
|
||||
$table->addIndex(['folder_id'], 'bookmarks_public_folder_id');
|
||||
$table->addIndex(['created_at'], 'bookmarks_public_created_at');
|
||||
}
|
||||
if (!$schema->hasTable('bookmarks_folders_shared')) {
|
||||
$table = $schema->createTable('bookmarks_folders_shared');
|
||||
$table->addColumn('folder_id', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('parent_folder', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('from_user', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('to_user', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('created_at', 'integer', [
|
||||
'notnull' => false,
|
||||
'length' => 4,
|
||||
'default' => 0,
|
||||
'unsigned' => true,
|
||||
]);
|
||||
$table->addColumn('index', 'bigint', [
|
||||
'notnull' => true,
|
||||
'length' => 64,
|
||||
'default' => 0
|
||||
]);
|
||||
$table->addColumn('can_edit', 'boolean', [
|
||||
'notnull' => true,
|
||||
'default' => false
|
||||
]);
|
||||
$table->addColumn('can_reshare', 'boolean', [
|
||||
'notnull' => true,
|
||||
'default' => false
|
||||
]);
|
||||
$table->addIndex(['created_at'], 'bookmarks_shared_created_at');
|
||||
$table->addIndex(['folder_id'], 'bookmarks_shared_folder_id');
|
||||
$table->addIndex(['from_user'], 'bookmarks_shared_from_user');
|
||||
$table->addIndex(['to_user'], 'bookmarks_shared_to_user');
|
||||
$table->addIndex(['parent_folder'], 'bookmarks_shared_parent');
|
||||
$table->addIndex(['to_user', 'parent_folder'], 'bookmarks_shared_userparent');
|
||||
$table->addIndex(['parent_folder', 'index'], 'bookmarks_shared_parentidx');
|
||||
$table->addIndex(['to_user', 'parent_folder', 'index'], 'bookmarks_share_userparentidx');
|
||||
}
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IOutput $output
|
||||
* @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
* @param array $options
|
||||
*/
|
||||
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace OCA\Bookmarks\Tests;
|
||||
|
||||
use OCA\Bookmarks\Db;
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
namespace OCA\Bookmarks\Tests;
|
||||
|
||||
use OCA\Bookmarks\Db;
|
||||
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
|
||||
use OCP\AppFramework\QueryException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PublicFolderTest extends TestCase {
|
||||
|
||||
/**
|
||||
* @var Db\FolderMapper
|
||||
*/
|
||||
private $folderMapper;
|
||||
|
||||
/**
|
||||
* @var Db\PublicFolderMapper
|
||||
*/
|
||||
private $folderPublicMapper;
|
||||
|
||||
/**
|
||||
* @var \OCP\IUserManager
|
||||
*/
|
||||
private $userManager;
|
||||
|
||||
/**
|
||||
* @var \OCP\AppFramework\Db\Entity
|
||||
*/
|
||||
private $folder;
|
||||
|
||||
/**
|
||||
* @var \OCP\AppFramework\Db\Entity
|
||||
*/
|
||||
private $publicFolder;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* @throws MultipleObjectsReturnedException
|
||||
* @throws QueryException
|
||||
* @throws \OC\DatabaseException
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*bookmarks');
|
||||
$query->execute();
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*bookmarks_tags');
|
||||
$query->execute();
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*bookmarks_folders');
|
||||
$query->execute();
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*bookmarks_folders_bookmarks');
|
||||
$query->execute();
|
||||
$query = \OC_DB::prepare('DELETE FROM *PREFIX*bookmarks_folders_public');
|
||||
$query->execute();
|
||||
|
||||
$this->folderPublicMapper = \OC::$server->query(Db\PublicFolderMapper::class);
|
||||
$this->folderMapper = \OC::$server->query(Db\FolderMapper::class);
|
||||
|
||||
$this->userManager = \OC::$server->getUserManager();
|
||||
$this->user = 'test';
|
||||
if (!$this->userManager->userExists($this->user)) {
|
||||
$this->userManager->createUser($this->user, 'password');
|
||||
}
|
||||
$this->userId = $this->userManager->get($this->user)->getUID();
|
||||
|
||||
$this->folder = Db\Folder::fromParams(['title' => 'test', 'parentFolder' => -1, 'userId' => $this->userId]);
|
||||
$this->folderMapper->insert($this->folder);
|
||||
|
||||
$this->publicFolder = Db\PublicFolder::fromParams(['folderId' => $this->folder->getId()]);
|
||||
$this->folderPublicMapper->insert($this->publicFolder);
|
||||
}
|
||||
|
||||
public function testCreateAndFind() {
|
||||
$f = $this->folderPublicMapper->find($this->publicFolder->getId());
|
||||
$this->assertSame($this->folder->getId(), $f->getFolderId());
|
||||
}
|
||||
|
||||
public function testFindByFolder() {
|
||||
$f = $this->folderPublicMapper->findByFolder($this->folder->getId());
|
||||
$this->assertSame($this->folder->getId(), $f->getFolderId());
|
||||
$this->assertSame($this->publicFolder->getId(), $f->getId());
|
||||
}
|
||||
|
||||
public function testFindCreatedBefore() {
|
||||
$f = $this->folderPublicMapper->findAllCreatedBefore(time());
|
||||
$this->assertSame($this->folder->getId(), $f[0]->getFolderId());
|
||||
$this->assertSame($this->publicFolder->getId(), $f[0]->getId());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue