]> git.mxchange.org Git - friendica.git/commitdiff
Improve the performance of API timeline calls
authorMichael <heluecht@pirati.ca>
Wed, 18 Oct 2023 08:11:36 +0000 (08:11 +0000)
committerMichael <heluecht@pirati.ca>
Wed, 18 Oct 2023 08:11:36 +0000 (08:11 +0000)
database.sql
src/Model/Post.php
src/Module/Api/Mastodon/Accounts/Statuses.php
src/Module/Api/Mastodon/Timelines/Home.php
src/Module/Api/Mastodon/Timelines/ListTimeline.php
src/Module/Api/Mastodon/Timelines/PublicTimeline.php
static/dbstructure.config.php
static/dbview.config.php

index 05fbe131f7c8e3c0ad9478f4efec59a94cdd6117..a6e29826be16db2342926d34accec5bf47079412 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2023.09-rc (Giant Rhubarb)
--- DB_UPDATE_VERSION 1537
+-- DB_UPDATE_VERSION 1538
 -- ------------------------------------------
 
 
@@ -1991,6 +1991,51 @@ CREATE VIEW `circle-member-view` AS SELECT
                        INNER JOIN `contact` ON `group_member`.`contact-id` = `contact`.`id`
                        INNER JOIN `group` ON `group_member`.`gid` = `group`.`id`;
 
+--
+-- VIEW post-timeline-view
+--
+DROP VIEW IF EXISTS `post-timeline-view`;
+CREATE VIEW `post-timeline-view` AS SELECT 
+       `post-user`.`uid` AS `uid`,
+       `post-user`.`uri-id` AS `uri-id`,
+       `post-user`.`gravity` AS `gravity`,
+       `post-user`.`created` AS `created`,
+       `post-user`.`edited` AS `edited`,
+       `post-thread-user`.`commented` AS `commented`,
+       `post-user`.`received` AS `received`,
+       `post-thread-user`.`changed` AS `changed`,
+       `post-user`.`private` AS `private`,
+       `post-user`.`visible` AS `visible`,
+       `post-user`.`deleted` AS `deleted`,
+       `post-user`.`origin` AS `origin`,
+       `post-user`.`global` AS `global`,
+       `post-user`.`network` AS `network`,
+       `post-user`.`protocol` AS `protocol`,
+       `post-user`.`vid` AS `vid`,
+       `post-user`.`contact-id` AS `contact-id`,
+       `contact`.`blocked` AS `contact-blocked`,
+       `contact`.`readonly` AS `contact-readonly`,
+       `contact`.`pending` AS `contact-pending`,
+       `contact`.`rel` AS `contact-rel`,
+       `contact`.`uid` AS `contact-uid`,
+       `contact`.`self` AS `self`,
+       `post-user`.`author-id` AS `author-id`,
+       `author`.`blocked` AS `author-blocked`,
+       `author`.`hidden` AS `author-hidden`,
+       `author`.`gsid` AS `author-gsid`,
+       `post-user`.`owner-id` AS `owner-id`,
+       `owner`.`blocked` AS `owner-blocked`,
+       `owner`.`gsid` AS `owner-gsid`,
+       `post-user`.`causer-id` AS `causer-id`,
+       `causer`.`blocked` AS `causer-blocked`,
+       `causer`.`gsid` AS `causer-gsid`
+       FROM `post-user`
+                       LEFT JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
+                       STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id`
+                       STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post-user`.`author-id`
+                       STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `post-user`.`owner-id`
+                       LEFT JOIN `contact` AS `causer` ON `causer`.`id` = `post-user`.`causer-id`;
+
 --
 -- VIEW post-user-view
 --
index fe484502212ae67895d4cadc888f3555c4163ba6..323b307fcdde13de0b76a7cf0862120e54a80bd4 100644 (file)
@@ -497,6 +497,23 @@ class Post
                return self::selectViewForUser('post-view', $uid, $selected, $condition, $params);
        }
 
+       /**
+        * Select rows from the post-timeline-view view for a given user
+        * This function is used for API calls.
+        *
+        * @param integer $uid       User ID
+        * @param array   $selected  Array of selected fields, empty for all
+        * @param array   $condition Array of fields for condition
+        * @param array   $params    Array of several parameters
+        *
+        * @return boolean|object
+        * @throws \Exception
+        */
+       public static function selectTimelineForUser(int $uid, array $selected = [], array $condition = [], array $params = [])
+       {
+               return self::selectViewForUser('post-timeline-view', $uid, $selected, $condition, $params);
+       }
+
        /**
         * Select rows from the post-thread-user-view view for a given user
         *
index b4e09b613e7dcc02bfb88c46a7a618b578d41d74..9093b5eab8ebdd36f31727a79f92d8f2544ce175 100644 (file)
@@ -74,8 +74,10 @@ class Statuses extends BaseApi
                } elseif ($request['only_media']) {
                        $condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'type' => [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]];
                } elseif (!$uid) {
-                       $condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
-                               'uid' => 0, 'network' => Protocol::FEDERATED];
+                       $condition = [
+                               'author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
+                               'uid' => 0, 'network' => Protocol::FEDERATED
+                       ];
                } else {
                        $condition = ["`author-id` = ? AND (`uid` = 0 OR (`uid` = ? AND NOT `global`))", $id, $uid];
                }
@@ -85,11 +87,15 @@ class Statuses extends BaseApi
 
                if (!$request['pinned'] && !$request['only_media']) {
                        if ($request['exclude_replies']) {
-                               $condition = DBA::mergeConditions($condition, ["(`gravity` = ? OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
-                                       Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]);
+                               $condition = DBA::mergeConditions($condition, [
+                                       "(`gravity` = ? OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
+                                       Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA
+                               ]);
                        } else {
-                               $condition = DBA::mergeConditions($condition, ["(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
-                                       Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]);
+                               $condition = DBA::mergeConditions($condition, [
+                                       "(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
+                                       Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA
+                               ]);
                        }
                } elseif ($request['exclude_replies']) {
                        $condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
@@ -100,7 +106,7 @@ class Statuses extends BaseApi
                } elseif ($request['only_media']) {
                        $items = DBA::select('media-view', ['uri-id'], $condition, $params);
                } else {
-                       $items = Post::selectForUser($uid, ['uri-id'], $condition, $params);
+                       $items = Post::selectTimelineForUser($uid, ['uri-id'], $condition, $params);
                }
 
                $display_quotes = self::appSupportsQuotes();
index d92a87636f5dd6f9fbbeccc3ca0d24dbddbf23e0..80d4826291e5eb9a5a442a7ddd39f247d8b76b31 100644 (file)
@@ -22,7 +22,6 @@
 namespace Friendica\Module\Api\Mastodon\Timelines;
 
 use Friendica\Core\Logger;
-use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Item;
@@ -67,8 +66,10 @@ class Home extends BaseApi
                }
 
                if ($request['only_media']) {
-                       $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
-                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
+                       $condition = DBA::mergeConditions($condition, [
+                               "`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
+                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO
+                       ]);
                }
 
                if ($request['remote']) {
@@ -79,7 +80,7 @@ class Home extends BaseApi
                        $condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
                }
 
-               $items = Post::selectForUser($uid, ['uri-id'], $condition, $params);
+               $items = Post::selectTimelineForUser($uid, ['uri-id'], $condition, $params);
 
                $display_quotes = self::appSupportsQuotes();
 
index 4331fc321cfa2bda5f89217ab9b8938369227311..147693f89139931b6dbbb327d7ddacae35c7e94b 100644 (file)
@@ -61,15 +61,19 @@ class ListTimeline extends BaseApi
                        'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
                ], $request);
 
-               $condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)",
-                       $uid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, $this->parameters['id']];
+               $condition = [
+                       "`uid` = ? AND `gravity` IN (?, ?) AND `contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)",
+                       $uid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, $this->parameters['id']
+               ];
 
                $condition = $this->addPagingConditions($request, $condition);
                $params = $this->buildOrderAndLimitParams($request);
 
                if ($request['only_media']) {
-                       $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
-                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
+                       $condition = DBA::mergeConditions($condition, [
+                               "`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
+                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO
+                       ]);
                }
 
                if ($request['exclude_replies']) {
@@ -84,7 +88,7 @@ class ListTimeline extends BaseApi
                        $condition = DBA::mergeConditions($condition, ["NOT `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin` AND `post-user`.`uri-id` = `post-user-view`.`uri-id`)"]);
                }
 
-               $items = Post::selectForUser($uid, ['uri-id'], $condition, $params);
+               $items = Post::selectTimelineForUser($uid, ['uri-id'], $condition, $params);
 
                $display_quotes = self::appSupportsQuotes();
 
index 057e2ec8d0530a0c497fe3a8d18866b0bf92388c..2692ca84b444105c39974108cdd6f4a3d24a9ade 100644 (file)
@@ -23,7 +23,6 @@ namespace Friendica\Module\Api\Mastodon\Timelines;
 
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
-use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Item;
@@ -57,30 +56,36 @@ class PublicTimeline extends BaseApi
                        'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
                ], $request);
 
-               $condition = ['gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'private' => Item::PUBLIC,
-                       'network' => Protocol::FEDERATED, 'author-blocked' => false, 'author-hidden' => false];
+               $condition = [
+                       'gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'private' => Item::PUBLIC,
+                       'network' => Protocol::FEDERATED, 'author-blocked' => false, 'author-hidden' => false
+               ];
 
                $condition = $this->addPagingConditions($request, $condition);
                $params = $this->buildOrderAndLimitParams($request);
 
                if ($request['local']) {
-                       $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin`)"]);
+                       $condition = DBA::mergeConditions($condition, ['origin' => true]);
+               } else {
+                       $condition = DBA::mergeConditions($condition, ['uid' => 0]);
                }
 
                if ($request['remote']) {
-                       $condition = DBA::mergeConditions($condition, ["NOT `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin` AND `post-user`.`uri-id` = `post-view`.`uri-id`)"]);
+                       $condition = DBA::mergeConditions($condition, ["NOT `uri-id` IN (SELECT `uri-id` FROM `post-user` WHERE `origin` AND `post-user`.`uri-id` = `post-timeline-view`.`uri-id`)"]);
                }
 
                if ($request['only_media']) {
-                       $condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
-                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
+                       $condition = DBA::mergeConditions($condition, [
+                               "`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
+                               Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO
+                       ]);
                }
 
                if ($request['exclude_replies']) {
                        $condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
                }
 
-               $items = Post::selectPostsForUser($uid, ['uri-id'], $condition, $params);
+               $items = Post::selectTimelineForUser($uid, ['uri-id'], $condition, $params);
 
                $display_quotes = self::appSupportsQuotes();
 
index b7a37708cd76d84ff3ac06e5e61009f4eb4ce972..e97d1ea1cd05dd3ad0fb626e3534c4589eda0f73 100644 (file)
@@ -56,7 +56,7 @@ use Friendica\Database\DBA;
 
 // This file is required several times during the test in DbaDefinition which justifies this condition
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1537);
+       define('DB_UPDATE_VERSION', 1538);
 }
 
 return [
index 057c8fccc5cc370955d79b45925853e60b278dd3..b4d10de83c426843b62aaaabcb26dd14d69b937b 100644 (file)
                        INNER JOIN `contact` ON `group_member`.`contact-id` = `contact`.`id`
                        INNER JOIN `group` ON `group_member`.`gid` = `group`.`id`"
        ],
+       "post-timeline-view" => [
+               "fields" => [
+                       "uid" => ["post-user", "uid"],
+                       "uri-id" => ["post-user", "uri-id"],
+                       "gravity" => ["post-user", "gravity"],
+                       "created" => ["post-user", "created"],
+                       "edited" => ["post-user", "edited"],
+                       "commented" => ["post-thread-user", "commented"],
+                       "received" => ["post-user", "received"],
+                       "changed" => ["post-thread-user", "changed"],
+                       "private" => ["post-user", "private"],
+                       "visible" => ["post-user", "visible"],
+                       "deleted" => ["post-user", "deleted"],
+                       "origin" => ["post-user", "origin"],
+                       "global" => ["post-user", "global"],
+                       "network" => ["post-user", "network"],
+                       "protocol" => ["post-user", "protocol"],
+                       "vid" => ["post-user", "vid"],
+                       "contact-id" => ["post-user", "contact-id"],
+                       "contact-blocked" => ["contact", "blocked"],
+                       "contact-readonly" => ["contact", "readonly"],
+                       "contact-pending" => ["contact", "pending"],
+                       "contact-rel" => ["contact", "rel"],
+                       "contact-uid" => ["contact", "uid"],
+                       "self" => ["contact", "self"],
+                       "author-id" => ["post-user", "author-id"],
+                       "author-blocked" => ["author", "blocked"],
+                       "author-hidden" => ["author", "hidden"],
+                       "author-gsid" => ["author", "gsid"],
+                       "owner-id" => ["post-user", "owner-id"],
+                       "owner-blocked" => ["owner", "blocked"],
+                       "owner-gsid" => ["owner", "gsid"],
+                       "causer-id" => ["post-user", "causer-id"],
+                       "causer-blocked" => ["causer", "blocked"],
+                       "causer-gsid" => ["causer", "gsid"],
+               ],
+               "query" => "FROM `post-user`
+                       LEFT JOIN `post-thread-user` ON `post-thread-user`.`uri-id` = `post-user`.`parent-uri-id` AND `post-thread-user`.`uid` = `post-user`.`uid`
+                       STRAIGHT_JOIN `contact` ON `contact`.`id` = `post-user`.`contact-id`
+                       STRAIGHT_JOIN `contact` AS `author` ON `author`.`id` = `post-user`.`author-id`
+                       STRAIGHT_JOIN `contact` AS `owner` ON `owner`.`id` = `post-user`.`owner-id`
+                       LEFT JOIN `contact` AS `causer` ON `causer`.`id` = `post-user`.`causer-id`"
+       ],
        "post-user-view" => [
                "fields" => [
                        "id" => ["post-user", "id"],