diff --git a/appinfo/info.xml b/appinfo/info.xml index 6eeb233f..4bda7b49 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -18,7 +18,7 @@ **🕸 Open standards:** We use the established ActivityPub standard! ]]> - 0.2.101 + 0.3 agpl Maxence Lange Julius Härtl @@ -32,7 +32,7 @@ https://github.com/nextcloud/social.git https://raw.githubusercontent.com/nextcloud/social/master/img/screenshot.png - + pgsql sqlite mysql diff --git a/composer.lock b/composer.lock index 0836bdf8..758e0955 100644 --- a/composer.lock +++ b/composer.lock @@ -12,12 +12,12 @@ "source": { "type": "git", "url": "https://github.com/daita/my-small-php-tools.git", - "reference": "2252b8e425e68331e70d4cfad412274af12e5c6f" + "reference": "d8778803612af20699c7efb0637bfe62478e596c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/2252b8e425e68331e70d4cfad412274af12e5c6f", - "reference": "2252b8e425e68331e70d4cfad412274af12e5c6f", + "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/d8778803612af20699c7efb0637bfe62478e596c", + "reference": "d8778803612af20699c7efb0637bfe62478e596c", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ } ], "description": "My small PHP Tools", - "time": "2019-10-03T11:59:56+00:00" + "time": "2020-03-18T23:09:45+00:00" }, { "name": "friendica/json-ld", @@ -448,16 +448,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", + "version": "4.3.4", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", + "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", "shasum": "" }, "require": { @@ -469,6 +469,7 @@ "require-dev": { "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", + "phpdocumentor/type-resolver": "0.4.*", "phpunit/phpunit": "^6.4" }, "type": "library", @@ -495,7 +496,7 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" + "time": "2019-12-28T18:55:12+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -544,33 +545,33 @@ }, { "name": "phpspec/prophecy", - "version": "1.9.0", + "version": "v1.10.3", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" + "reference": "451c3cd1418cf640de218914901e51b064abb093" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", - "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", + "phpspec/phpspec": "^2.5 || ^3.2", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev" + "dev-master": "1.10.x-dev" } }, "autoload": { @@ -603,7 +604,7 @@ "spy", "stub" ], - "time": "2019-10-03T11:07:50+00:00" + "time": "2020-03-05T15:02:03+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1559,16 +1560,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", "shasum": "" }, "require": { @@ -1580,7 +1581,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -1613,7 +1614,7 @@ "polyfill", "portable" ], - "time": "2019-08-06T08:03:45+00:00" + "time": "2020-05-12T16:14:59+00:00" }, { "name": "theseer/tokenizer", @@ -1657,31 +1658,29 @@ }, { "name": "webmozart/assert", - "version": "1.5.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", + "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", "shasum": "" }, "require": { "php": "^5.3.3 || ^7.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "vimeo/psalm": "<3.9.1" + }, "require-dev": { "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -1703,7 +1702,7 @@ "check", "validate" ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2020-04-18T12:12:48+00:00" } ], "aliases": [], diff --git a/lib/AP.php b/lib/AP.php index fbdeeb11..ec3251a1 100644 --- a/lib/AP.php +++ b/lib/AP.php @@ -307,7 +307,7 @@ class AP { case Announce::TYPE: $item = new Announce(); - $item->setHiddenOnTimeline(true); + $item->setFilterDuplicate(true); break; case Block::TYPE: diff --git a/lib/Command/CheckInstall.php b/lib/Command/CheckInstall.php index 4a2cd6a8..c01d85fb 100644 --- a/lib/Command/CheckInstall.php +++ b/lib/Command/CheckInstall.php @@ -177,7 +177,8 @@ class CheckInstall extends Base { throw new Exception('unknown user'); } - $wrapper = $this->pushService->testOnAccount($userId); + // push was not implemented on 18 +// $wrapper = $this->pushService->testOnAccount($userId); $output->writeln(json_encode($wrapper, JSON_PRETTY_PRINT)); diff --git a/lib/Db/ActionsRequest.php b/lib/Db/ActionsRequest.php index 979164ea..3ad0c125 100644 --- a/lib/Db/ActionsRequest.php +++ b/lib/Db/ActionsRequest.php @@ -60,8 +60,10 @@ class ActionsRequest extends ActionsRequestBuilder { $qb = $this->getActionsInsertSql(); $qb->setValue('id', $qb->createNamedParameter($like->getId())) ->setValue('actor_id', $qb->createNamedParameter($like->getActorId())) + ->setValue('actor_id_prim', $qb->createNamedParameter($qb->prim($like->getActorId()))) ->setValue('type', $qb->createNamedParameter($like->getType())) - ->setValue('object_id', $qb->createNamedParameter($like->getObjectId())); + ->setValue('object_id', $qb->createNamedParameter($like->getObjectId())) + ->setValue('object_id_prim', $qb->createNamedParameter($qb->prim($like->getObjectId()))); try { $qb->setValue( @@ -88,18 +90,11 @@ class ActionsRequest extends ActionsRequestBuilder { */ public function getAction(string $actorId, string $objectId, string $type): ACore { $qb = $this->getActionsSelectSql(); - $this->limitToActorId($qb, $actorId); - $this->limitToObjectId($qb, $objectId); - $this->limitToType($qb, $type); + $qb->limitToActorIdPrim($qb->prim($actorId)); + $qb->limitToObjectIdPrim($qb->prim($objectId)); + $qb->limitToType($type); - $cursor = $qb->execute(); - $data = $cursor->fetch(); - $cursor->closeCursor(); - if ($data === false) { - throw new ActionDoesNotExistException(); - } - - return $this->parseActionsSelectSql($data); + return $this->getActionFromRequest($qb); } @@ -111,18 +106,12 @@ class ActionsRequest extends ActionsRequestBuilder { */ public function getActionFromItem(ACore $item): ACore { $qb = $this->getActionsSelectSql(); - $this->limitToActorId($qb, $item->getActorId()); - $this->limitToObjectId($qb, $item->getObjectId()); - $this->limitToType($qb, $item->getType()); - $cursor = $qb->execute(); - $data = $cursor->fetch(); - $cursor->closeCursor(); - if ($data === false) { - throw new ActionDoesNotExistException(); - } + $qb->limitToActorIdPrim($qb->prim($item->getActorId())); + $qb->limitToObjectIdPrim($qb->prim($item->getObjectId())); + $qb->limitToType($item->getType()); - return $this->parseActionsSelectSql($data); + return $this->getActionFromRequest($qb); } @@ -134,8 +123,8 @@ class ActionsRequest extends ActionsRequestBuilder { */ public function countActions(string $objectId, string $type): int { $qb = $this->countActionsSelectSql(); - $this->limitToObjectId($qb, $objectId); - $this->limitToType($qb, $type); + $qb->limitToObjectIdPrim($qb->prim($objectId)); + $qb->limitToType($type); $cursor = $qb->execute(); $data = $cursor->fetch(); @@ -152,17 +141,10 @@ class ActionsRequest extends ActionsRequestBuilder { */ public function getByObjectId(string $objectId): array { $qb = $this->getActionsSelectSql(); - $this->limitToObjectId($qb, $objectId); + $qb->limitToObjectIdPrim($qb->prim($objectId)); $this->leftJoinCacheActors($qb, 'actor_id'); - $likes = []; - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $likes[] = $this->parseActionsSelectSql($data); - } - $cursor->closeCursor(); - - return $likes; + return $this->getActionsFromRequest($qb); } @@ -178,15 +160,15 @@ class ActionsRequest extends ActionsRequestBuilder { } - /** - * @param string $objectId - */ - public function deleteLikes(string $objectId) { - $qb = $this->getActionsDeleteSql(); - $this->limitToObjectId($qb, $objectId); - - $qb->execute(); - } +// /** +// * @param string $objectId +// */ +// public function deleteLikes(string $objectId) { +// $qb = $this->getActionsDeleteSql(); +// $this->limitToObjectId($qb, $objectId); +// +// $qb->execute(); +// } } diff --git a/lib/Db/ActionsRequestBuilder.php b/lib/Db/ActionsRequestBuilder.php index a72ae102..5bf74e8f 100644 --- a/lib/Db/ActionsRequestBuilder.php +++ b/lib/Db/ActionsRequestBuilder.php @@ -31,10 +31,11 @@ declare(strict_types=1); namespace OCA\Social\Db; +use daita\MySmallPhpTools\Exceptions\RowNotFoundException; use daita\MySmallPhpTools\Traits\TArrayTools; +use OCA\Social\Exceptions\ActionDoesNotExistException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\ACore; -use OCP\DB\QueryBuilder\IQueryBuilder; /** @@ -51,10 +52,10 @@ class ActionsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Insert request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getActionsInsertSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); + protected function getActionsInsertSql(): SocialQueryBuilder { + $qb = $this->getQueryBuilder(); $qb->insert(self::TABLE_ACTIONS); return $qb; @@ -64,10 +65,10 @@ class ActionsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Update request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getActionsUpdateSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); + protected function getActionsUpdateSql(): SocialQueryBuilder { + $qb = $this->getQueryBuilder(); $qb->update(self::TABLE_ACTIONS); return $qb; @@ -77,10 +78,10 @@ class ActionsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Select request for Shares * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getActionsSelectSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); + protected function getActionsSelectSql(): SocialQueryBuilder { + $qb = $this->getQueryBuilder(); /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->select('a.id', 'a.type', 'a.actor_id', 'a.object_id', 'a.creation') @@ -95,10 +96,10 @@ class ActionsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Select request for Shares * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function countActionsSelectSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); + protected function countActionsSelectSql(): SocialQueryBuilder { + $qb = $this->getQueryBuilder(); $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') ->from(self::TABLE_ACTIONS, 'a'); @@ -111,16 +112,47 @@ class ActionsRequestBuilder extends CoreRequestBuilder { /** * Base of the Sql Delete request * - * @return IQueryBuilder + * @return SocialQueryBuilder */ - protected function getActionsDeleteSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); + protected function getActionsDeleteSql(): SocialQueryBuilder { + $qb = $this->getQueryBuilder(); $qb->delete(self::TABLE_ACTIONS); return $qb; } + /** + * @param SocialQueryBuilder $qb + * + * @return ACore + * @throws ActionDoesNotExistException + */ + protected function getActionFromRequest(SocialQueryBuilder $qb): ACore { + /** @var ACore $result */ + try { + $result = $qb->getRow([$this, 'parseActionsSelectSql']); + } catch (RowNotFoundException $e) { + throw new ActionDoesNotExistException($e->getMessage()); + } + + return $result; + } + + + /** + * @param SocialQueryBuilder $qb + * + * @return ACore[] + */ + public function getActionsFromRequest(SocialQueryBuilder $qb): array { + /** @var ACore[] $result */ + $result = $qb->getRows([$this, 'parseActionsSelectSql']); + + return $result; + } + + /** * @param array $data * diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 0c6f3592..622805eb 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -60,21 +60,21 @@ use OCP\ILogger; class CoreRequestBuilder { - const TABLE_REQUEST_QUEUE = 'social_a2_req_queue'; + const TABLE_REQUEST_QUEUE = 'social_3_req_queue'; - const TABLE_ACTORS = 'social_a2_actors'; - const TABLE_STREAM = 'social_a2_stream'; - const TABLE_STREAM_DEST = 'social_a2_stream_dest'; - const TABLE_STREAM_TAGS = 'social_a2_stream_tags'; - const TABLE_STREAM_QUEUE = 'social_a2_stream_queue'; - const TABLE_STREAM_ACTIONS = 'social_a2_stream_act'; + const TABLE_ACTORS = 'social_3_actor'; + const TABLE_STREAM = 'social_3_stream'; + const TABLE_STREAM_DEST = 'social_3_stream_dest'; + const TABLE_STREAM_TAGS = 'social_3_stream_tag'; + const TABLE_STREAM_QUEUE = 'social_3_stream_queue'; + const TABLE_STREAM_ACTIONS = 'social_3_stream_act'; - const TABLE_HASHTAGS = 'social_a2_hashtags'; - const TABLE_FOLLOWS = 'social_a2_follows'; - const TABLE_ACTIONS = 'social_a2_actions'; + const TABLE_HASHTAGS = 'social_3_hashtag'; + const TABLE_FOLLOWS = 'social_3_follow'; + const TABLE_ACTIONS = 'social_3_action'; - const TABLE_CACHE_ACTORS = 'social_a2_cache_actors'; - const TABLE_CACHE_DOCUMENTS = 'social_a2_cache_docum'; + const TABLE_CACHE_ACTORS = 'social_3_cache_actor'; + const TABLE_CACHE_DOCUMENTS = 'social_3_cache_doc'; /** @var array */ private $tables = [ @@ -104,7 +104,6 @@ class CoreRequestBuilder { /** @var MiscService */ protected $miscService; - /** @var Person */ protected $viewer = null; @@ -192,9 +191,11 @@ class CoreRequestBuilder { /** * Limit the request to the Id - * @deprecated + * * @param IQueryBuilder $qb * @param int $id + * + * @deprecated */ protected function limitToId(IQueryBuilder &$qb, int $id) { $this->limitToDBFieldInt($qb, 'id', $id); @@ -203,10 +204,12 @@ class CoreRequestBuilder { /** * Limit the request to the Id (string) - * @deprecated * * @param IQueryBuilder $qb * @param string $id + * + * @deprecated + * */ protected function limitToIdString(IQueryBuilder &$qb, string $id) { $this->limitToDBField($qb, 'id', $id, false); @@ -215,10 +218,12 @@ class CoreRequestBuilder { /** * Limit the request to the UserId - * @deprecated * * @param IQueryBuilder $qb * @param string $userId + * + * @deprecated + * */ protected function limitToUserId(IQueryBuilder &$qb, string $userId) { $this->limitToDBField($qb, 'user_id', $userId, false); @@ -238,9 +243,11 @@ class CoreRequestBuilder { /** * Limit the request to the Id (string) - * @deprecated + * * @param IQueryBuilder $qb * @param string $id + * + * @deprecated */ protected function limitToInReplyTo(IQueryBuilder &$qb, string $id) { $this->limitToDBField($qb, 'in_reply_to', $id, false); @@ -774,9 +781,10 @@ class CoreRequestBuilder { /** - * @deprecated * @param IQueryBuilder $qb * @param string $alias + * + * @deprecated */ protected function selectCacheActors(IQueryBuilder &$qb, string $alias = 'ca') { if ($qb->getType() !== QueryBuilder::SELECT) { diff --git a/lib/Db/SocialFiltersQueryBuilder.php b/lib/Db/SocialFiltersQueryBuilder.php index d0aca550..a9f323c1 100644 --- a/lib/Db/SocialFiltersQueryBuilder.php +++ b/lib/Db/SocialFiltersQueryBuilder.php @@ -55,7 +55,7 @@ class SocialFiltersQueryBuilder extends SocialLimitsQueryBuilder { $expr = $this->expr(); $filter = $expr->orX(); - $filter->add($this->exprLimitToDBFieldInt('hidden_on_timeline', 0, 's')); + $filter->add($this->exprLimitToDBFieldInt('filter_duplicate', 0, 's')); $follower = $expr->andX(); $follower->add($this->exprLimitToDBField('attributed_to_prim', $this->prim($viewer->getId()), false)); diff --git a/lib/Db/SocialLimitsQueryBuilder.php b/lib/Db/SocialLimitsQueryBuilder.php index 1af01eed..a82cddb3 100644 --- a/lib/Db/SocialLimitsQueryBuilder.php +++ b/lib/Db/SocialLimitsQueryBuilder.php @@ -164,6 +164,17 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { } + /** + * Limit the request to the ActorId + * + * @param string $actorId + * @param string $alias + */ + public function limitToActorIdPrim(string $actorId, string $alias = '') { + $this->limitToDBField('actor_id', $actorId, false, $alias); + } + + /** * Limit the request to the FollowId * @@ -195,6 +206,17 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { } + /** + * Limit the request to the ActorId + * + * @param string $actorId + * @param string $alias + */ + public function limitToObjectIdPrim(string $actorId, string $alias = '') { + $this->limitToDBField('object_id_prim', $actorId, false, $alias); + } + + /** * Limit the request to the account * diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php index 9a2d9f0f..db1480f4 100644 --- a/lib/Db/StreamRequest.php +++ b/lib/Db/StreamRequest.php @@ -666,6 +666,7 @@ class StreamRequest extends StreamRequestBuilder { ->setValue('attributed_to', $qb->createNamedParameter($attributedTo)) ->setValue('attributed_to_prim', $qb->createNamedParameter($qb->prim($attributedTo))) ->setValue('in_reply_to', $qb->createNamedParameter($stream->getInReplyTo())) + ->setValue('in_reply_to_prim', $qb->createNamedParameter($qb->prim($stream->getInReplyTo()))) ->setValue('source', $qb->createNamedParameter($stream->getSource())) ->setValue('activity_id', $qb->createNamedParameter($stream->getActivityId())) ->setValue('object_id', $qb->createNamedParameter($stream->getObjectId())) @@ -673,8 +674,8 @@ class StreamRequest extends StreamRequestBuilder { ->setValue('details', $qb->createNamedParameter(json_encode($stream->getDetailsAll()))) ->setValue('cache', $qb->createNamedParameter($cache)) ->setValue( - 'hidden_on_timeline', - $qb->createNamedParameter(($stream->isHiddenOnTimeline()) ? '1' : '0') + 'filter_duplicate', + $qb->createNamedParameter(($stream->isFilterDuplicate()) ? '1' : '0') ) ->setValue( 'instances', $qb->createNamedParameter( diff --git a/lib/Db/StreamRequestBuilder.php b/lib/Db/StreamRequestBuilder.php index f13d4403..50046149 100644 --- a/lib/Db/StreamRequestBuilder.php +++ b/lib/Db/StreamRequestBuilder.php @@ -95,7 +95,7 @@ class StreamRequestBuilder extends CoreRequestBuilder { 's.type', 's.subtype', 's.to', 's.to_array', 's.cc', 's.bcc', 's.content', 's.summary', 's.attachments', 's.published', 's.published_time', 's.cache', 's.object_id', 's.attributed_to', 's.in_reply_to', 's.source', 's.local', - 's.instances', 's.creation', 's.hidden_on_timeline', 's.details', 's.hashtags' + 's.instances', 's.creation', 's.filter_duplicate', 's.details', 's.hashtags' ) ->from(self::TABLE_STREAM, 's'); diff --git a/lib/Migration/Version0002Date20190622000001.php b/lib/Migration/Version0002Date20190622000001.php deleted file mode 100644 index 7e8aaa8b..00000000 --- a/lib/Migration/Version0002Date20190622000001.php +++ /dev/null @@ -1,404 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Schema\SchemaException; -use Doctrine\DBAL\Types\Type; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -/** - * Class Version0002Date20190226000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20190622000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - if (!$schema->hasTable('social_a2_stream')) { - return $schema; - } - - $table = $schema->getTable('social_a2_stream'); - if (!$table->hasColumn('details')) { - $table->addColumn( - 'details', Type::TEXT, - [ - 'notnull' => false - ] - ); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - -// $qb = $this->connection->getQueryBuilder(); -// $qb->delete('social_a2_stream'); -// $expr = $qb->expr(); -// $qb->where($expr->eq('type', $qb->createNamedParameter('Announce'))); -// -// $qb->execute(); - - $this->check( - $schema, 'id', 'social_server_follows', 'social_a2_follows', 'accepted', 'boolean' - ); - $this->check( - $schema, 'id', 'social_server_notes', 'social_a2_stream', 'local', 'boolean' - ); - $this->check( - $schema, 'id', 'social_cache_actors', 'social_a2_cache_actors', 'local', 'boolean' - ); - $this->check( - $schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'public', - 'boolean' - ); - - - $this->check( - $schema, 'id', 'social_server_actors', 'social_a2_actors', 'creation', 'datetime' - ); - $this->check( - $schema, 'id', 'social_server_follows', 'social_a2_follows', 'creation', 'datetime' - ); - $this->check( - $schema, 'id', 'social_server_notes', 'social_a2_stream', 'creation', 'datetime' - ); - $this->check( - $schema, 'id', 'social_cache_actors', 'social_a2_cache_actors', 'creation', - 'datetime' - ); - $this->check( - $schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'creation', - 'datetime' - ); - - $this->check( - $schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'caching', - 'datetime' - ); - -// $this->check($schema, 'id', 'social_request_queue', 'social_a2_req_queue','last', 'datetime'); -// $this->check($schema, 'id', 'social_queue_stream', 'social_a2_stream_queue', 'last', 'datetime'); - - $this->check( - $schema, 'id', 'social_server_notes', 'social_a2_stream', 'published_time', - 'datetime' - ); - } - - - private function check( - ISchemaWrapper $schema, - string $prim, - string $source, - string $dest, - string $field, - string $type - ) { - if (!$schema->hasTable($source)) { - return; - } - - $qb = $this->connection->getQueryBuilder(); - $qb->select($prim, $field) - ->from($source); - - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $this->fixMigration($dest, $prim, $field, $type, $data); - } - - $cursor->closeCursor(); - } - - - /** - * @param string $k - * @param array $arr - * @param string $default - * - * @return string - */ - private function get(string $k, array $arr, string $default = ''): string { - if ($arr === null) { - return $default; - } - - if (!array_key_exists($k, $arr)) { - $subs = explode('.', $k, 2); - if (sizeof($subs) > 1) { - if (!array_key_exists($subs[0], $arr)) { - return $default; - } - - $r = $arr[$subs[0]]; - if (!is_array($r)) { - return $default; - } - - return $this->get($subs[1], $r, $default); - } else { - return $default; - } - } - - if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) { - return $default; - } - - return (string)$arr[$k]; - } - - - /** - * @param string $k - * @param array $arr - * @param bool $default - * - * @return bool - */ - protected function getBool(string $k, array $arr, bool $default = false): bool { - if ($arr === null) { - return $default; - } - - if (!array_key_exists($k, $arr)) { - $subs = explode('.', $k, 2); - if (sizeof($subs) > 1) { - if (!array_key_exists($subs[0], $arr)) { - return $default; - } - - return $this->getBool($subs[1], $arr[$subs[0]], $default); - } else { - return $default; - } - } - - if ($arr[$k] === null) { - return $default; - } - - if (is_bool($arr[$k])) { - return $arr[$k]; - } - - if ($arr[$k] === '1') { - return true; - } - - if ($arr[$k] === '0') { - return false; - } - - return $default; - } - - - -// -// -// /** -// * @param string $table -// * @param array $fields -// * @param array $data -// * -// * @throws Exception -// */ -// private function insertInto(string $table, array $fields, array $data) { -// $insert = $this->connection->getQueryBuilder(); -// $insert->insert($table); -// -// $datetimeFields = [ -// 'creation', -// 'last', -// 'caching', -// 'published_time' -// ]; -// -// $booleanFields = [ -// 'local', -// 'public', -// 'accepted', -// 'hidden_on_timeline' -// ]; -// -// foreach ($fields as $field) { -// $value = $this->get($field, $data, ''); -// if ($field === 'id_prim' -// && $value === '' -// && $this->get('id', $data, '') !== '') { -// $value = hash('sha512', $this->get('id', $data, '')); -// } -// -// if (in_array($field, $datetimeFields) && $value === '') { -// $insert->setValue( -// $field, -// $insert->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) -// ); -// } else if (in_array($field, $booleanFields) && $value === '') { -// $insert->setValue( -// $field, $insert->createNamedParameter('0') -// ); -// } else { -// $insert->setValue( -// $field, $insert->createNamedParameter($value) -// ); -// } -// } -// -// try { -// $insert->execute(); -// } catch (UniqueConstraintViolationException $e) { -// } -// } - - - /** - * @param string $dest - * @param string $prim - * @param string $field - * @param string $type - * @param array $old - */ - private function fixMigration( - string $dest, string $prim, string $field, string $type, array $old - ) { - -// foreach ($fields as $field) { -// $value = $this->get($field, $data, ''); -// if ($field === 'id_prim' -// && $value === '' -// && $this->get('id', $data, '') !== '') { -// $value = hash('sha512', $this->get('id', $data, '')); -// } - - $current = $this->connection->getQueryBuilder(); - $current->select($field) - ->from($dest); - - $cursor = $current->execute(); - $data = $cursor->fetch(); - $cursor->closeCursor(); - - if ($data === false) { - return; - } - - switch ($type) { - case 'datetime': - $oldValue = $this->get($field, $old); - $oldId = $this->get($prim, $old); - $currValue = $this->get($field, $data, ''); - if ($currValue !== '') { - return; - } - - if ($oldValue === '') { - $oldValue = null; - } - - $update = $this->connection->getQueryBuilder(); - $update->update($dest); - $update->set($field, $update->createNamedParameter($oldValue)); - $expr = $update->expr(); - - $update->where($expr->eq($prim, $update->createNamedParameter($oldId))); - - try { - $update->execute(); - } catch (Exception $e) { - } - break; - - case 'boolean': - $oldValue = $this->getBool($field, $old); - $oldId = $this->get($prim, $old); - $update = $this->connection->getQueryBuilder(); - $update->update($dest); - $update->set($field, $update->createNamedParameter(($oldValue) ? '1' : '0')); - $expr = $update->expr(); - - $update->where($expr->eq($prim, $update->createNamedParameter($oldId))); - - $update->execute(); - - - break; - } - } - - -} - diff --git a/lib/Migration/Version0002Date20190629000001.php b/lib/Migration/Version0002Date20190629000001.php deleted file mode 100644 index dbed67f4..00000000 --- a/lib/Migration/Version0002Date20190629000001.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Schema\SchemaException; -use Doctrine\DBAL\Types\Type; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -/** - * Class Version0002Date20190226000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20190629000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - if ($schema->hasTable('social_a2_stream')) { - $table = $schema->getTable('social_a2_stream'); - if (!$table->hasColumn('subtype')) { - $table->addColumn( - 'subtype', Type::STRING, - [ - 'notnull' => false, - 'length' => 31, - ] - ); - } - } - - - if (!$schema->hasTable('social_a2_actions')) { - $table = $schema->createTable('social_a2_actions'); - - $table->addColumn( - 'id', 'string', - [ - 'notnull' => false, - 'length' => 1000 - ] - ); - $table->addColumn( - 'id_prim', 'string', - [ - 'notnull' => false, - 'length' => 128 - ] - ); - $table->addColumn( - 'type', 'string', - [ - 'notnull' => false, - 'length' => 31, - ] - ); - $table->addColumn( - 'actor_id', 'string', - [ - 'notnull' => true, - 'length' => 1000, - ] - ); - $table->addColumn( - 'object_id', 'string', - [ - 'notnull' => true, - 'length' => 1000, - ] - ); - $table->addColumn( - 'creation', 'datetime', - [ - 'notnull' => false, - ] - ); - - $table->setPrimaryKey(['id_prim']); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - $qb = $this->connection->getQueryBuilder(); - $qb->delete('social_a2_stream'); - $expr = $qb->expr(); - $qb->where($expr->eq('type', $qb->createNamedParameter('SocialAppNotification'))); - - $qb->execute(); - } - -} - diff --git a/lib/Migration/Version0002Date20190717000001.php b/lib/Migration/Version0002Date20190717000001.php deleted file mode 100644 index 568d0975..00000000 --- a/lib/Migration/Version0002Date20190717000001.php +++ /dev/null @@ -1,105 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Schema\SchemaException; -use Doctrine\DBAL\Types\Type; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -/** - * Class Version0002Date20190717000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20190717000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - if (!$schema->hasTable('social_a2_cache_docum')) { - return $schema; - } - - $table = $schema->getTable('social_a2_cache_docum'); - if (!$table->hasColumn('resized_copy')) { - $table->addColumn( - 'resized_copy', Type::TEXT, - [ - 'notnull' => false - ] - ); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - } - -} - diff --git a/lib/Migration/Version0002Date20190925000001.php b/lib/Migration/Version0002Date20190925000001.php deleted file mode 100644 index c7ac1589..00000000 --- a/lib/Migration/Version0002Date20190925000001.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Exception\UniqueConstraintViolationException; -use Doctrine\DBAL\Schema\SchemaException; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -/** - * Class Version0002Date20190925000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20190925000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $table = $schema->getTable('social_a2_stream_act'); - if (!$table->hasColumn('liked')) { - $table->addColumn('liked', 'boolean'); - } - if (!$table->hasColumn('boosted')) { - $table->addColumn('boosted', 'boolean'); - } - if (!$table->hasColumn('replied')) { - $table->addColumn('replied', 'boolean'); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $this->fillTableStreamActions($schema); - } - - /** - * @param ISchemaWrapper $schema - */ - private function fillTableStreamActions(ISchemaWrapper $schema) { - - $start = 0; - $limit = 1000; - while (true) { - $qb = $this->connection->getQueryBuilder(); - $qb->select('id', 'actor_id', 'stream_id', 'values') - ->from('social_a2_stream_act') - ->setMaxResults(1000) - ->setFirstResult($start); - - $cursor = $qb->execute(); - $count = 0; - while ($data = $cursor->fetch()) { - $count++; - - $this->updateStreamActions($data); - } - $cursor->closeCursor(); - - $start += $count; - if ($count < $limit) { - break; - } - } - } - - - /** - * @param array $data - */ - private function updateStreamActions(array $data) { - $update = $this->connection->getQueryBuilder(); - $update->update('social_a2_stream_act'); - - $id = $data['id']; - $actorId = $data['actor_id']; - $streamId = $data['stream_id']; - - $values = json_decode($data['values'], true); - $liked = (array_key_exists('liked', $values) && ($values['liked'])) ? 1 : 0; - $boosted = (array_key_exists('boosted', $values) && $values['boosted']) ? 1 : 0; - $replied = (array_key_exists('replied', $values) && $values['replied']) ? 1 : 0; - - $update->set('actor_id_prim', $update->createNamedParameter(hash('sha512', $actorId))); - $update->set('stream_id_prim', $update->createNamedParameter(hash('sha512', $streamId))); - $update->set('liked', $update->createNamedParameter($liked)); - $update->set('boosted', $update->createNamedParameter($boosted)); - $update->set('replied', $update->createNamedParameter($replied)); - - $expr = $update->expr(); - $update->where($expr->eq('id', $update->createNamedParameter($id))); - try { - $update->execute(); - } catch (UniqueConstraintViolationException $e) { - } - } - -} diff --git a/lib/Migration/Version0002Date20191001000001.php b/lib/Migration/Version0002Date20191001000001.php deleted file mode 100644 index 86888a13..00000000 --- a/lib/Migration/Version0002Date20191001000001.php +++ /dev/null @@ -1,177 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Exception\UniqueConstraintViolationException; -use Doctrine\DBAL\Schema\SchemaException; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -/** - * Class Version0002Date20191001000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20191001000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - if (!$schema->hasTable('social_a2_stream_tags')) { - $table = $schema->createTable('social_a2_stream_tags'); - - $table->addColumn( - 'stream_id', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - $table->addColumn( - 'hashtag', 'string', - [ - 'notnull' => false, - 'length' => 127, - ] - ); - - if (!$table->hasIndex('sh')) { - $table->addUniqueIndex(['stream_id', 'hashtag'], 'sh'); - } - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $this->fillTableStreamHashtags($schema); - } - - /** - * @param ISchemaWrapper $schema - */ - private function fillTableStreamHashtags(ISchemaWrapper $schema) { - - $start = 0; - $limit = 1000; - while (true) { - $qb = $this->connection->getQueryBuilder(); - $qb->select('id', 'hashtags') - ->from('social_a2_stream') - ->setMaxResults(1000) - ->setFirstResult($start); - - $cursor = $qb->execute(); - $count = 0; - while ($data = $cursor->fetch()) { - $count++; - - $this->updateStreamTags($data); - } - $cursor->closeCursor(); - - $start += $count; - if ($count < $limit) { - break; - } - } - } - - - /** - * @param array $data - */ - private function updateStreamTags(array $data) { - if ($data['hashtags'] === '' || $data['hashtags'] === null) { - return; - } - - $id = $data['id']; - $tags = json_decode($data['hashtags'], true); - - foreach ($tags as $tag) { - if ($tag === '') { - continue; - } - $insert = $this->connection->getQueryBuilder(); - $insert->insert('social_a2_stream_tags'); - - $insert->setValue('stream_id', $insert->createNamedParameter(hash('sha512', $id))); - $insert->setValue('hashtag', $insert->createNamedParameter($tag)); - try { - $insert->execute(); - } catch (UniqueConstraintViolationException $e) { - } - } - - } - -} diff --git a/lib/Migration/Version0002Date20191010000001.php b/lib/Migration/Version0002Date20191010000001.php deleted file mode 100644 index d754d419..00000000 --- a/lib/Migration/Version0002Date20191010000001.php +++ /dev/null @@ -1,387 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Schema\SchemaException; -use Exception; -use OCA\Social\Db\StreamDestRequest; -use OCA\Social\Db\StreamRequest; -use OCA\Social\Db\StreamTagsRequest; -use OCP\AppFramework\QueryException; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -require_once __DIR__ . '/../../appinfo/autoload.php'; - - -/** - * Class Version0002Date20191010000001 - * - * @package OCA\Social\Migration - */ -class Version0002Date20191010000001 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $table = $schema->getTable('social_a2_follows'); - if (!$table->hasColumn('follow_id_prim')) { - $table->addColumn( - 'follow_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - if (!$table->hasColumn('actor_id_prim')) { - $table->addColumn( - 'actor_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - if (!$table->hasColumn('object_id_prim')) { - $table->addColumn( - 'object_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - - if (!$schema->hasTable('social_a2_stream_dest')) { - $table = $schema->createTable('social_a2_stream_dest'); - - $table->addColumn( - 'stream_id', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - $table->addColumn( - 'actor_id', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - $table->addColumn( - 'type', 'string', - [ - 'notnull' => false, - 'length' => 15, - ] - ); - $table->addColumn( - 'subtype', 'string', - [ - 'notnull' => false, - 'length' => 7, - ] - ); - - $table->addUniqueIndex(['stream_id', 'actor_id', 'type'], 'sat'); - $table->addIndex(['type', 'subtype'], 'ts'); - } - - - $table = $schema->getTable('social_a2_stream'); - if (!$table->hasColumn('in_reply_to_prim')) { - $table->addColumn( - 'in_reply_to_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - if (!$table->hasColumn('object_id_prim')) { - $table->addColumn( - 'object_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - if (!$table->hasColumn('attributed_to_prim')) { - $table->addColumn( - 'attributed_to_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - - - $table = $schema->getTable('social_a2_stream_act'); - if (!$table->hasColumn('actor_id_prim')) { - $table->addColumn( - 'actor_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - if (!$table->hasColumn('stream_id_prim')) { - $table->addColumn( - 'stream_id_prim', 'string', - [ - 'notnull' => true, - 'length' => 128, - ] - ); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $this->updateTableStream($schema); - $this->updateTableFollows($schema); - $this->updateTableStreamActions($schema); - $this->fillTableStreamDest($schema); - } - - - /** - * @param ISchemaWrapper $schema - */ - private function updateTableFollows(ISchemaWrapper $schema) { - if (!$schema->hasTable('social_a2_follows')) { - return; - } - - $qb = $this->connection->getQueryBuilder(); - $qb->select('*') - ->from('social_a2_follows'); - - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $this->updateFollowPrim($data); - } - - $cursor->closeCursor(); - } - - /** - * @param array $data - */ - private function updateFollowPrim(array $data) { - if ($data['follow_id_prim'] !== '') { - return; - } - - $update = $this->connection->getQueryBuilder(); - $update->update('social_a2_follows'); - $update->set('follow_id_prim', $update->createNamedParameter(hash('sha512', $data['follow_id']))); - $update->set('object_id_prim', $update->createNamedParameter(hash('sha512', $data['object_id']))); - $update->set('actor_id_prim', $update->createNamedParameter(hash('sha512', $data['actor_id']))); - - $expr = $update->expr(); - $update->where($expr->eq('id_prim', $update->createNamedParameter($data['id_prim']))); - - $update->execute(); - } - - - /** - * @param ISchemaWrapper $schema - */ - private function updateTableStreamActions(ISchemaWrapper $schema) { - if (!$schema->hasTable('social_a2_stream_act')) { - return; - } - - $qb = $this->connection->getQueryBuilder(); - $qb->select('*') - ->from('social_a2_stream_act'); - - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $this->updateStreamActionsPrim($data); - } - - $cursor->closeCursor(); - } - - /** - * @param array $data - */ - private function updateStreamActionsPrim(array $data) { - if ($data['actor_id_prim'] !== '') { - return; - } - - $update = $this->connection->getQueryBuilder(); - $update->update('social_a2_stream_act'); - $update->set('stream_id_prim', $update->createNamedParameter(hash('sha512', $data['stream_id']))); - $update->set('actor_id_prim', $update->createNamedParameter(hash('sha512', $data['actor_id']))); - - $expr = $update->expr(); - $update->where($expr->eq('stream_id', $update->createNamedParameter($data['stream_id']))); - $update->andWhere($expr->eq('actor_id', $update->createNamedParameter($data['actor_id']))); - - $update->execute(); - } - - - /** - * @param ISchemaWrapper $schema - */ - private function updateTableStream(ISchemaWrapper $schema) { - if (!$schema->hasTable('social_a2_stream')) { - return; - } - - $qb = $this->connection->getQueryBuilder(); - $qb->select('id_prim', 'object_id', 'attributed_to', 'in_reply_to') - ->from('social_a2_stream'); - - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $this->updateStreamPrim($data); - } - - $cursor->closeCursor(); - } - - - /** - * @param array $data - */ - private function updateStreamPrim(array $data) { - $update = $this->connection->getQueryBuilder(); - $update->update('social_a2_stream'); - if ($data['object_id'] !== '') { - $update->set('object_id_prim', $update->createNamedParameter(hash('sha512', $data['object_id']))); - } - if ($data['in_reply_to'] !== '') { - $update->set( - 'in_reply_to_prim', $update->createNamedParameter(hash('sha512', $data['in_reply_to'])) - ); - } - $update->set( - 'attributed_to_prim', $update->createNamedParameter(hash('sha512', $data['attributed_to'])) - ); - - $expr = $update->expr(); - $update->where($expr->eq('id_prim', $update->createNamedParameter($data['id_prim']))); - - $update->execute(); - } - - - /** - * @param ISchemaWrapper $schema - */ - private function fillTableStreamDest(ISchemaWrapper $schema) { - if (!$schema->hasTable('social_a2_stream')) { - return; - } - - try { - $streamRequest = \OC::$server->query(StreamRequest::class); - $streamDestRequest = \OC::$server->query(StreamDestRequest::class); - $streamTagsRequest = \OC::$server->query(StreamTagsRequest::class); - } catch (QueryException $e) { - \OC::$server->getLogger() - ->log(2, 'issue while querying stream* request'); - - return; - } - - $streamDestRequest->emptyStreamDest(); - $streamTagsRequest->emptyStreamTags(); - $streams = $streamRequest->getAll(); - - foreach ($streams as $stream) { - try { - $streamDestRequest->generateStreamDest($stream); - $streamTagsRequest->generateStreamTags($stream); - } catch (Exception $e) { - \OC::$server->getLogger() - ->log( - 2, '-- ' . get_class($e) . ' - ' . $e->getMessage() . ' - ' . json_encode( - $stream - ) - ); - } - } - } - -} diff --git a/lib/Migration/Version0002Date20191010000002.php b/lib/Migration/Version0002Date20191010000002.php deleted file mode 100644 index 4810bf2b..00000000 --- a/lib/Migration/Version0002Date20191010000002.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright 2018, Maxence Lange - * @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 . - * - */ - - -namespace OCA\Social\Migration; - - -use Closure; -use Doctrine\DBAL\Schema\SchemaException; -use Exception; -use OCP\DB\ISchemaWrapper; -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\SimpleMigrationStep; - - -require_once __DIR__ . '/../../appinfo/autoload.php'; - - -/** - * Class Version0002Date20191010000002 - * - * @package OCA\Social\Migration - */ -class Version0002Date20191010000002 extends SimpleMigrationStep { - - - /** @var IDBConnection */ - private $connection; - - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @return ISchemaWrapper - * @throws SchemaException - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options - ): ISchemaWrapper { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - - $table = $schema->getTable('social_a2_follows'); - if (!$table->hasIndex('afoa')) { - $table->addUniqueIndex(['accepted', 'follow_id_prim', 'object_id_prim', 'actor_id_prim'], 'afoa'); - } - if (!$table->hasIndex('aoa')) { - $table->addUniqueIndex(['accepted', 'object_id_prim', 'actor_id_prim'], 'aoa'); - } - - - $table = $schema->getTable('social_a2_stream'); - if (!$table->hasIndex('ipoha')) { - $table->addUniqueIndex( - ['id_prim', 'published_time', 'object_id_prim', 'hidden_on_timeline', 'attributed_to_prim'], - 'ipoha' - ); - } - if (!$table->hasIndex('id_prim')) { - $table->addUniqueIndex( - ['id_prim'], - 'id_prim' - ); - } - if (!$table->hasIndex('object_id_prim')) { - $table->addIndex( - ['object_id_prim'], - 'object_id_prim' - ); - } - if (!$table->hasIndex('in_reply_to_prim')) { - $table->addIndex( - ['in_reply_to_prim'], - 'in_reply_to_prim' - ); - } - if (!$table->hasIndex('attributed_to_prim')) { - $table->addIndex( - ['attributed_to_prim'], - 'attributed_to_prim' - ); - } - - - $table = $schema->getTable('social_a2_cache_actors'); - if ($table->hasIndex('i')) { - $table->renameIndex('i', 'id_prim'); - } else if (!$table->hasIndex('id_prim')) { - $table->addUniqueIndex(['id_prim'], 'id_prim'); - } - - return $schema; - } - - - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * - * @throws Exception - */ - public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - } - - -} diff --git a/lib/Migration/Version0002Date20190506000001.php b/lib/Migration/Version0003Date20200611000001.php similarity index 63% rename from lib/Migration/Version0002Date20190506000001.php rename to lib/Migration/Version0003Date20200611000001.php index 9a8f334e..c8621ede 100644 --- a/lib/Migration/Version0002Date20190506000001.php +++ b/lib/Migration/Version0003Date20200611000001.php @@ -32,31 +32,20 @@ namespace OCA\Social\Migration; use Closure; -use DateTime; -use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use Doctrine\DBAL\Types\Type; use Exception; use OCP\DB\ISchemaWrapper; -use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; -// notes on migration for A3: -// -// 'details' in _stream -// 'hidden_on_timeline' in _stream should be replaced by ' -//filter_duplicate' -// -// - /** - * Class Version0002Date20190226000001 + * Class Version0003Date20200611000001 * * @package OCA\Social\Migration */ -class Version0002Date20190506000001 extends SimpleMigrationStep { +class Version0003Date20200611000001 extends SimpleMigrationStep { /** @var IDBConnection */ @@ -83,15 +72,18 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { /** @var ISchemaWrapper $schema */ $schema = $schemaClosure(); + $this->createActions($schema); $this->createActors($schema); - $this->createFollows($schema); - $this->createHashtags($schema); - $this->createStreams($schema); $this->createCacheActors($schema); $this->createCacheDocuments($schema); + $this->createFollows($schema); + $this->createHashtags($schema); $this->createRequestQueue($schema); + $this->createStreams($schema); $this->createStreamActions($schema); + $this->createStreamDest($schema); $this->createStreamQueue($schema); + $this->createStreamTags($schema); return $schema; } @@ -105,19 +97,76 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @throws Exception */ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + } - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); - $this->fillActors($schema); - $this->fillFollows($schema); - $this->fillHashtags($schema); - $this->fillStreams($schema); - $this->fillCacheActors($schema); - $this->fillCacheDocuments($schema); - $this->fillRequestQueue($schema); - $this->fillStreamActions($schema); - $this->fillStreamQueue($schema); + /** + * @param ISchemaWrapper $schema + */ + private function createActions(ISchemaWrapper $schema) { + if ($schema->hasTable('social_3_action')) { + return; + } + + $table = $schema->createTable('social_3_action'); + $table->addColumn( + 'id', 'string', + [ + 'notnull' => false, + 'length' => 1000 + ] + ); + $table->addColumn( + 'id_prim', 'string', + [ + 'notnull' => false, + 'length' => 128 + ] + ); + $table->addColumn( + 'type', 'string', + [ + 'notnull' => false, + 'length' => 31, + ] + ); + $table->addColumn( + 'actor_id', 'string', + [ + 'notnull' => true, + 'length' => 1000, + ] + ); + $table->addColumn( + 'actor_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn( + 'object_id', 'string', + [ + 'notnull' => true, + 'length' => 1000, + ] + ); + $table->addColumn( + 'object_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn( + 'creation', 'datetime', + [ + 'notnull' => false, + ] + ); + + $table->setPrimaryKey(['id_prim']); + $table->addUniqueIndex(['actor_id_prim', 'object_id_prim', 'type'], 'aot'); } @@ -125,11 +174,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createActors(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_actors')) { + if ($schema->hasTable('social_3_actor')) { return; } - $table = $schema->createTable('social_a2_actors'); + $table = $schema->createTable('social_3_actor'); $table->addColumn( 'id', 'string', @@ -206,13 +255,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createFollows(ISchemaWrapper $schema) { - - if ($schema->hasTable('social_a2_follows')) { + if ($schema->hasTable('social_3_follow')) { return; } - $table = $schema->createTable('social_a2_follows'); - + $table = $schema->createTable('social_3_follow'); $table->addColumn( 'id', 'string', [ @@ -241,6 +288,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'actor_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'object_id', 'string', [ @@ -248,6 +302,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'object_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'follow_id', 'string', [ @@ -255,6 +316,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'follow_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'accepted', 'boolean', [ @@ -270,6 +338,8 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { ); $table->setPrimaryKey(['id_prim']); + $table->addUniqueIndex(['accepted', 'follow_id_prim', 'object_id_prim', 'actor_id_prim'], 'afoa'); + $table->addUniqueIndex(['accepted', 'object_id_prim', 'actor_id_prim'], 'aoa'); } @@ -277,11 +347,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createHashtags(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_hashtags')) { + if ($schema->hasTable('social_3_hashtag')) { return; } - $table = $schema->createTable('social_a2_hashtags'); + $table = $schema->createTable('social_3_hashtag'); $table->addColumn( 'hashtag', 'string', [ @@ -305,11 +375,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createStreams(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_stream')) { + if ($schema->hasTable('social_3_stream')) { return; } - $table = $schema->createTable('social_a2_stream'); + $table = $schema->createTable('social_3_stream'); $table->addColumn( 'id', 'string', @@ -332,6 +402,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 31, ] ); + $table->addColumn( + 'subtype', Type::STRING, + [ + 'notnull' => true, + 'length' => 31, + ] + ); $table->addColumn( 'to', 'string', [ @@ -389,6 +466,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'attributed_to_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'in_reply_to', 'string', [ @@ -396,6 +480,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'in_reply_to_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'activity_id', 'string', [ @@ -410,6 +501,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'object_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'hashtags', 'string', [ @@ -417,6 +515,12 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'details', Type::TEXT, + [ + 'notnull' => true + ] + ); $table->addColumn( 'source', Type::TEXT, [ @@ -455,7 +559,7 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { ] ); $table->addColumn( - 'hidden_on_timeline', 'boolean', + 'filter_duplicate', 'boolean', [ 'notnull' => true, 'default' => false @@ -463,6 +567,19 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { ); $table->setPrimaryKey(['id_prim']); + $table->addUniqueIndex( + [ + 'id_prim', + 'published_time', + 'object_id_prim', + 'filter_duplicate', + 'attributed_to_prim' + ], + 'ipoha' + ); + $table->addIndex(['object_id_prim'], 'object_id_prim'); + $table->addIndex(['in_reply_to_prim'], 'in_reply_to_prim'); + $table->addIndex(['attributed_to_prim'], 'attributed_to_prim'); } @@ -470,11 +587,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createCacheActors(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_cache_actors')) { + if ($schema->hasTable('social_3_cache_actor')) { return; } - $table = $schema->createTable('social_a2_cache_actors'); + $table = $schema->createTable('social_3_cache_actor'); $table->addColumn( 'id', 'string', [ @@ -619,11 +736,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createCacheDocuments(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_cache_docum')) { + if ($schema->hasTable('social_3_cache_doc')) { return; } - $table = $schema->createTable('social_a2_cache_docum'); + $table = $schema->createTable('social_3_cache_doc'); $table->addColumn( 'id', 'string', [ @@ -680,6 +797,12 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'resized_copy', Type::TEXT, + [ + 'notnull' => true + ] + ); $table->addColumn( 'public', 'boolean', [ @@ -716,11 +839,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createRequestQueue(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_req_queue')) { + if ($schema->hasTable('social_3_req_queue')) { return; } - $table = $schema->createTable('social_a2_req_queue'); + $table = $schema->createTable('social_3_req_queue'); $table->addColumn( 'id', 'bigint', [ @@ -796,11 +919,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createStreamActions(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_stream_act')) { + if ($schema->hasTable('social_3_stream_act')) { return; } - $table = $schema->createTable('social_a2_stream_act'); + $table = $schema->createTable('social_3_stream_act'); $table->addColumn( 'id', Type::INTEGER, @@ -818,6 +941,13 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'actor_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); $table->addColumn( 'stream_id', 'string', [ @@ -825,6 +955,16 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { 'length' => 1000, ] ); + $table->addColumn( + 'stream_id_prim', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn('liked', 'boolean'); + $table->addColumn('boosted', 'boolean'); + $table->addColumn('replied', 'boolean'); $table->addColumn( 'values', Type::TEXT, [ @@ -833,6 +973,50 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { ); $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['stream_id_prim', 'actor_id_prim'], 'sa'); + } + + + /** + * @param ISchemaWrapper $schema + */ + private function createStreamDest(ISchemaWrapper $schema) { + if ($schema->hasTable('social_3_stream_dest')) { + return; + } + + $table = $schema->createTable('social_3_stream_dest'); + $table->addColumn( + 'stream_id', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn( + 'actor_id', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn( + 'type', 'string', + [ + 'notnull' => false, + 'length' => 15, + ] + ); + $table->addColumn( + 'subtype', 'string', + [ + 'notnull' => false, + 'length' => 7, + ] + ); + + $table->addUniqueIndex(['stream_id', 'actor_id', 'type'], 'sat'); + $table->addIndex(['type', 'subtype'], 'ts'); } @@ -840,11 +1024,11 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { * @param ISchemaWrapper $schema */ private function createStreamQueue(ISchemaWrapper $schema) { - if ($schema->hasTable('social_a2_stream_queue')) { + if ($schema->hasTable('social_3_stream_queue')) { return; } - $table = $schema->createTable('social_a2_stream_queue'); + $table = $schema->createTable('social_3_stream_queue'); $table->addColumn( 'id', 'bigint', [ @@ -903,370 +1087,31 @@ class Version0002Date20190506000001 extends SimpleMigrationStep { /** * @param ISchemaWrapper $schema - * - * @throws Exception */ - private function fillActors(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_server_actors', 'social_a2_actors', - [ - 'id', - 'id_prim', - 'user_id', - 'preferred_username', - 'name', - 'summary', - 'public_key', - 'private_key', - 'avatar_version', - 'creation' - ] - ); - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillFollows(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_server_follows', 'social_a2_follows', - [ - 'id', - 'id_prim', - 'type', - 'actor_id', - 'object_id', - 'follow_id', - 'accepted', - 'creation' - ] - ); - } - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillHashtags(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_server_hashtags', 'social_a2_hashtags', - [ - 'hashtag', - 'trend' - ] - ); - - -// if (!$schema->hasTable('social_server_hashtags')) { -// return; -// } -// -// $qb = $this->connection->getQueryBuilder(); -// $qb->select('*') -// ->from('social_server_hashtags'); -// -// $cursor = $qb->execute(); -// while ($data = $cursor->fetch()) { -// $insert = $this->connection->getQueryBuilder(); -// $insert->insert('social_a2_hashtags'); -// -// $insert->setValue( -// 'hashtag', $insert->createNamedParameter($this->get('hashtag', $data, '')) -// ) -// ->setValue( -// 'trend', $insert->createNamedParameter($this->get('trend', $data, '')) -// ); -// -// $insert->execute(); -// } -// -// $cursor->closeCursor(); - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillStreams(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_server_notes', 'social_a2_stream', - [ - 'id', - 'id_prim', - 'type', - 'to', - 'to_array', - 'cc', - 'bcc', - 'content', - 'summary', - 'published', - 'published_time', - 'attributed_to', - 'in_reply_to', - 'activity_id', - 'object_id', - 'hashtags', - 'source', - 'instances', - 'attachments', - 'cache', - 'creation', - 'local' - ] - ); - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillCacheActors(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_cache_actors', 'social_a2_cache_actors', - [ - 'id', - 'id_prim', - 'type', - 'account', - 'local', - 'following', - 'followers', - 'inbox', - 'shared_inbox', - 'outbox', - 'featured', - 'url', - 'preferred_username', - 'name', - 'icon_id', - 'summary', - 'public_key', - 'source', - 'details', - 'creation' - ] - ); - } - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillCacheDocuments(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_cache_documents', 'social_a2_cache_docum', - [ - 'id', - 'id_prim', - 'type', - 'parent_id', - 'media_type', - 'mime_type', - 'url', - 'local_copy', - 'public', - 'error', - 'creation', - 'caching' - ] - ); - - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillRequestQueue(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_request_queue', 'social_a2_req_queue', - [ - 'id', - 'token', - 'author', - 'activity', - 'instance', - 'priority', - 'status', - 'tries', - 'last' - ] - ); - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillStreamActions(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_stream_actions', 'social_a2_stream_act', - [ - 'id', - 'actor_id', - 'stream_id', - 'values' - ] - ); - } - - - /** - * @param ISchemaWrapper $schema - * - * @throws Exception - */ - private function fillStreamQueue(ISchemaWrapper $schema) { - $this->duplicateTable( - $schema, 'social_queue_stream', 'social_a2_stream_queue', - [ - 'id', - 'token', - 'stream_id', - 'type', - 'status', - 'tries', - 'last' - ] - ); - } - - - /** - * @param string $k - * @param array $arr - * @param string $default - * - * @return string - */ - private function get(string $k, array $arr, string $default = ''): string { - if ($arr === null) { - return $default; - } - - if (!array_key_exists($k, $arr)) { - $subs = explode('.', $k, 2); - if (sizeof($subs) > 1) { - if (!array_key_exists($subs[0], $arr)) { - return $default; - } - - $r = $arr[$subs[0]]; - if (!is_array($r)) { - return $default; - } - - return $this->get($subs[1], $r, $default); - } else { - return $default; - } - } - - if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) { - return $default; - } - - return (string)$arr[$k]; - } - - - /** - * @param ISchemaWrapper $schema - * @param string $source - * @param string $dest - * @param array $fields - * - * @throws Exception - */ - private function duplicateTable( - ISchemaWrapper $schema, string $source, string $dest, array $fields - ) { - if (!$schema->hasTable($source)) { + private function createStreamTags(ISchemaWrapper $schema) { + if ($schema->hasTable('social_3_stream_tag')) { return; } - $qb = $this->connection->getQueryBuilder(); - $qb->select('*') - ->from($source); + $table = $schema->createTable('social_3_stream_tag'); - $cursor = $qb->execute(); - while ($data = $cursor->fetch()) { - $this->insertInto($dest, $fields, $data); - } + $table->addColumn( + 'stream_id', 'string', + [ + 'notnull' => true, + 'length' => 128, + ] + ); + $table->addColumn( + 'hashtag', 'string', + [ + 'notnull' => false, + 'length' => 127, + ] + ); - $cursor->closeCursor(); + $table->addUniqueIndex(['stream_id', 'hashtag'], 'sh'); } - - /** - * @param string $table - * @param array $fields - * @param array $data - * - * @throws Exception - */ - private function insertInto(string $table, array $fields, array $data) { - $insert = $this->connection->getQueryBuilder(); - $insert->insert($table); - - $datetimeFields = [ - 'creation', - 'last', - 'caching', - 'published_time' - ]; - - $booleanFields = [ - 'local', - 'public', - 'accepted', - 'hidden_on_timeline' - ]; - - foreach ($fields as $field) { - $value = $this->get($field, $data, ''); - if ($field === 'id_prim' - && $value === '' - && $this->get('id', $data, '') !== '') { - $value = hash('sha512', $this->get('id', $data, '')); - } - - if (in_array($field, $datetimeFields) && $value === '') { - $insert->setValue( - $field, - $insert->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) - ); - } else if (in_array($field, $booleanFields) && $value === '') { - $insert->setValue( - $field, $insert->createNamedParameter('0') - ); - } else { - $insert->setValue( - $field, $insert->createNamedParameter($value) - ); - } - } - - try { - $insert->execute(); - } catch (UniqueConstraintViolationException $e) { - } - } - - } diff --git a/lib/Model/ActivityPub/Stream.php b/lib/Model/ActivityPub/Stream.php index b6061e57..382d98b0 100644 --- a/lib/Model/ActivityPub/Stream.php +++ b/lib/Model/ActivityPub/Stream.php @@ -92,7 +92,7 @@ class Stream extends ACore implements IQueryRow, JsonSerializable { private $timeline = ''; /** @var bool */ - private $hiddenOnTimeline = false; + private $filterDuplicate = false; /** @@ -335,17 +335,17 @@ class Stream extends ACore implements IQueryRow, JsonSerializable { /** * @return bool */ - public function isHiddenOnTimeline(): bool { - return $this->hiddenOnTimeline; + public function isFilterDuplicate(): bool { + return $this->filterDuplicate; } /** - * @param bool $hiddenOnTimeline + * @param bool $filterDuplicate * * @return Stream */ - public function setHiddenOnTimeline(bool $hiddenOnTimeline): Stream { - $this->hiddenOnTimeline = $hiddenOnTimeline; + public function setFilterDuplicate(bool $filterDuplicate): Stream { + $this->filterDuplicate = $filterDuplicate; return $this; } @@ -385,7 +385,7 @@ class Stream extends ACore implements IQueryRow, JsonSerializable { $this->setAttributedTo($this->validate(self::AS_ID, 'attributed_to', $data, '')); $this->setInReplyTo($this->validate(self::AS_ID, 'in_reply_to', $data)); $this->setDetailsAll($this->getArray('details', $data, [])); - $this->setHiddenOnTimeline($this->getBool('hidden_on_timeline', $data, false)); + $this->setFilterDuplicate($this->getBool('filter_duplicate', $data, false)); $cache = new Cache(); $cache->import($this->getArray('cache', $data, [])); diff --git a/lib/Service/PushService.php b/lib/Service/PushService.php index 913fc6c4..4986ab15 100644 --- a/lib/Service/PushService.php +++ b/lib/Service/PushService.php @@ -33,14 +33,14 @@ namespace OCA\Social\Service; use daita\MySmallPhpTools\Traits\TAsync; use OC; -use OC\Push\Model\Helper\PushCallback; +//use OC\Push\Model\Helper\PushCallback; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\StreamNotFoundException; use OCA\Social\Model\ActivityPub\Actor\Person; use OCP\AppFramework\QueryException; -use OCP\Push\Exceptions\PushInstallException; -use OCP\Push\IPushManager; -use OCP\Push\Model\IPushWrapper; +//use OCP\Push\Exceptions\PushInstallException; +//use OCP\Push\IPushManager; +//use OCP\Push\Model\IPushWrapper; /** @@ -53,9 +53,9 @@ class PushService { use TAsync; - - /** @var IPushManager */ - private $pushManager; +// +// /** @var IPushManager */ +// private $pushManager; /** @var DetailsService */ private $detailsService; @@ -82,13 +82,13 @@ class PushService { $this->miscService = $miscService; // FIX ME: nc18/push - if ($this->miscService->getNcVersion() >= 19) { - try { - $this->pushManager = OC::$server->query(IPushManager::class); - } catch (QueryException $e) { - $miscService->log('QueryException while loading IPushManager - ' . $e->getMessage()); - } - } +// if ($this->miscService->getNcVersion() >= 19) { +// try { +// $this->pushManager = OC::$server->query(IPushManager::class); +// } catch (QueryException $e) { +// $miscService->log('QueryException while loading IPushManager - ' . $e->getMessage()); +// } +// } } @@ -96,65 +96,65 @@ class PushService { * @param string $streamId */ public function onNewStream(string $streamId) { - // FIXME: remove in nc18 - if ($this->miscService->getNcVersion() < 19) { - return; - } - - if (!$this->pushManager->isAvailable()) { - return; - } - - try { - $stream = $this->streamService->getStreamById($streamId); - } catch (StreamNotFoundException $e) { - return; - } - - try { - $pushHelper = $this->pushManager->getPushHelper(); - $details = $this->detailsService->generateDetailsFromStream($stream); - } catch (PushInstallException $e) { - return; - } catch (SocialAppConfigException $e) { - return; - } - - $home = array_map( - function(Person $item): string { - return $item->getUserId(); - }, $details->getHomeViewers() - ); - - $callback = new PushCallback('social', 'timeline.home'); - $callback->setPayloadSerializable($stream); - $callback->addUsers($home); - $pushHelper->toCallback($callback); - - $direct = array_map( - function(Person $item): string { - return $item->getUserId(); - }, $details->getDirectViewers() - ); - - $callback = new PushCallback('social', 'timeline.direct'); - $callback->addUsers($direct); - $callback->setPayloadSerializable($stream); - $pushHelper->toCallback($callback); + return; +// if ($this->miscService->getNcVersion() < 19) { +// return; +// } +// +// if (!$this->pushManager->isAvailable()) { +// return; +// } +// +// try { +// $stream = $this->streamService->getStreamById($streamId); +// } catch (StreamNotFoundException $e) { +// return; +// } +// +// try { +// $pushHelper = $this->pushManager->getPushHelper(); +// $details = $this->detailsService->generateDetailsFromStream($stream); +// } catch (PushInstallException $e) { +// return; +// } catch (SocialAppConfigException $e) { +// return; +// } +// +// $home = array_map( +// function(Person $item): string { +// return $item->getUserId(); +// }, $details->getHomeViewers() +// ); +// +// $callback = new PushCallback('social', 'timeline.home'); +// $callback->setPayloadSerializable($stream); +// $callback->addUsers($home); +// $pushHelper->toCallback($callback); +// +// $direct = array_map( +// function(Person $item): string { +// return $item->getUserId(); +// }, $details->getDirectViewers() +// ); +// +// $callback = new PushCallback('social', 'timeline.direct'); +// $callback->addUsers($direct); +// $callback->setPayloadSerializable($stream); +// $pushHelper->toCallback($callback); } - - /** - * @param $userId - * - * @return IPushWrapper - * @throws PushInstallException - */ - public function testOnAccount(string $userId): IPushWrapper { - $pushHelper = $this->pushManager->getPushHelper(); - - return $pushHelper->test($userId); - } +// +// /** +// * @param $userId +// * +// * @return IPushWrapper +// * @throws PushInstallException +// */ +// public function testOnAccount(string $userId): IPushWrapper { +//// $pushHelper = $this->pushManager->getPushHelper(); +//// +//// return $pushHelper->test($userId); +// } } diff --git a/lib/Service/StreamService.php b/lib/Service/StreamService.php index a14f2656..d6bb64c2 100644 --- a/lib/Service/StreamService.php +++ b/lib/Service/StreamService.php @@ -257,7 +257,7 @@ class StreamService { if ($type === Stream::TYPE_DIRECT) { $instancePath->setPriority(InstancePath::PRIORITY_HIGH); $stream->addToArray($actor->getId()); - $stream->setHiddenOnTimeline(true); + $stream->setFilterDuplicate(true); } else { $stream->addCc($actor->getId()); }