mirror of
https://github.com/friendica/friendica
synced 2024-11-09 16:22:56 +00:00
Improve the performance of API timeline calls
This commit is contained in:
parent
2cd18fd4bf
commit
1c67be8db0
8 changed files with 147 additions and 26 deletions
47
database.sql
47
database.sql
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2023.09-rc (Giant Rhubarb)
|
-- 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 `contact` ON `group_member`.`contact-id` = `contact`.`id`
|
||||||
INNER JOIN `group` ON `group_member`.`gid` = `group`.`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
|
-- VIEW post-user-view
|
||||||
--
|
--
|
||||||
|
|
|
@ -497,6 +497,23 @@ class Post
|
||||||
return self::selectViewForUser('post-view', $uid, $selected, $condition, $params);
|
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
|
* Select rows from the post-thread-user-view view for a given user
|
||||||
*
|
*
|
||||||
|
|
|
@ -74,8 +74,10 @@ class Statuses extends BaseApi
|
||||||
} elseif ($request['only_media']) {
|
} elseif ($request['only_media']) {
|
||||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'type' => [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]];
|
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED], 'type' => [Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]];
|
||||||
} elseif (!$uid) {
|
} elseif (!$uid) {
|
||||||
$condition = ['author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
|
$condition = [
|
||||||
'uid' => 0, 'network' => Protocol::FEDERATED];
|
'author-id' => $id, 'private' => [Item::PUBLIC, Item::UNLISTED],
|
||||||
|
'uid' => 0, 'network' => Protocol::FEDERATED
|
||||||
|
];
|
||||||
} else {
|
} else {
|
||||||
$condition = ["`author-id` = ? AND (`uid` = 0 OR (`uid` = ? AND NOT `global`))", $id, $uid];
|
$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['pinned'] && !$request['only_media']) {
|
||||||
if ($request['exclude_replies']) {
|
if ($request['exclude_replies']) {
|
||||||
$condition = DBA::mergeConditions($condition, ["(`gravity` = ? OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
|
$condition = DBA::mergeConditions($condition, [
|
||||||
Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]);
|
"(`gravity` = ? OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
|
||||||
|
Item::GRAVITY_PARENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
$condition = DBA::mergeConditions($condition, ["(`gravity` IN (?, ?) OR (`gravity` = ? AND `vid` = ? AND `protocol` != ?))",
|
$condition = DBA::mergeConditions($condition, [
|
||||||
Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, Item::GRAVITY_ACTIVITY, Verb::getID(Activity::ANNOUNCE), Conversation::PARCEL_DIASPORA]);
|
"(`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']) {
|
} elseif ($request['exclude_replies']) {
|
||||||
$condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
|
$condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
|
||||||
|
@ -100,7 +106,7 @@ class Statuses extends BaseApi
|
||||||
} elseif ($request['only_media']) {
|
} elseif ($request['only_media']) {
|
||||||
$items = DBA::select('media-view', ['uri-id'], $condition, $params);
|
$items = DBA::select('media-view', ['uri-id'], $condition, $params);
|
||||||
} else {
|
} else {
|
||||||
$items = Post::selectForUser($uid, ['uri-id'], $condition, $params);
|
$items = Post::selectTimelineForUser($uid, ['uri-id'], $condition, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
$display_quotes = self::appSupportsQuotes();
|
$display_quotes = self::appSupportsQuotes();
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
namespace Friendica\Module\Api\Mastodon\Timelines;
|
namespace Friendica\Module\Api\Mastodon\Timelines;
|
||||||
|
|
||||||
use Friendica\Core\Logger;
|
use Friendica\Core\Logger;
|
||||||
use Friendica\Core\System;
|
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
|
@ -67,8 +66,10 @@ class Home extends BaseApi
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request['only_media']) {
|
if ($request['only_media']) {
|
||||||
$condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
|
$condition = DBA::mergeConditions($condition, [
|
||||||
Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
|
"`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
|
||||||
|
Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request['remote']) {
|
if ($request['remote']) {
|
||||||
|
@ -79,7 +80,7 @@ class Home extends BaseApi
|
||||||
$condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
|
$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();
|
$display_quotes = self::appSupportsQuotes();
|
||||||
|
|
||||||
|
|
|
@ -61,15 +61,19 @@ class ListTimeline extends BaseApi
|
||||||
'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
|
'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
|
||||||
], $request);
|
], $request);
|
||||||
|
|
||||||
$condition = ["`uid` = ? AND `gravity` IN (?, ?) AND `contact-id` IN (SELECT `contact-id` FROM `group_member` WHERE `gid` = ?)",
|
$condition = [
|
||||||
$uid, Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT, $this->parameters['id']];
|
"`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);
|
$condition = $this->addPagingConditions($request, $condition);
|
||||||
$params = $this->buildOrderAndLimitParams($request);
|
$params = $this->buildOrderAndLimitParams($request);
|
||||||
|
|
||||||
if ($request['only_media']) {
|
if ($request['only_media']) {
|
||||||
$condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
|
$condition = DBA::mergeConditions($condition, [
|
||||||
Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
|
"`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']) {
|
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`)"]);
|
$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();
|
$display_quotes = self::appSupportsQuotes();
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ namespace Friendica\Module\Api\Mastodon\Timelines;
|
||||||
|
|
||||||
use Friendica\Core\Logger;
|
use Friendica\Core\Logger;
|
||||||
use Friendica\Core\Protocol;
|
use Friendica\Core\Protocol;
|
||||||
use Friendica\Core\System;
|
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
use Friendica\Model\Item;
|
use Friendica\Model\Item;
|
||||||
|
@ -57,30 +56,36 @@ class PublicTimeline extends BaseApi
|
||||||
'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
|
'friendica_order' => TimelineOrderByTypes::ID, // Sort order options (defaults to ID)
|
||||||
], $request);
|
], $request);
|
||||||
|
|
||||||
$condition = ['gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'private' => Item::PUBLIC,
|
$condition = [
|
||||||
'network' => Protocol::FEDERATED, 'author-blocked' => false, 'author-hidden' => false];
|
'gravity' => [Item::GRAVITY_PARENT, Item::GRAVITY_COMMENT], 'private' => Item::PUBLIC,
|
||||||
|
'network' => Protocol::FEDERATED, 'author-blocked' => false, 'author-hidden' => false
|
||||||
|
];
|
||||||
|
|
||||||
$condition = $this->addPagingConditions($request, $condition);
|
$condition = $this->addPagingConditions($request, $condition);
|
||||||
$params = $this->buildOrderAndLimitParams($request);
|
$params = $this->buildOrderAndLimitParams($request);
|
||||||
|
|
||||||
if ($request['local']) {
|
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']) {
|
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']) {
|
if ($request['only_media']) {
|
||||||
$condition = DBA::mergeConditions($condition, ["`uri-id` IN (SELECT `uri-id` FROM `post-media` WHERE `type` IN (?, ?, ?))",
|
$condition = DBA::mergeConditions($condition, [
|
||||||
Post\Media::AUDIO, Post\Media::IMAGE, Post\Media::VIDEO]);
|
"`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']) {
|
if ($request['exclude_replies']) {
|
||||||
$condition = DBA::mergeConditions($condition, ['gravity' => Item::GRAVITY_PARENT]);
|
$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();
|
$display_quotes = self::appSupportsQuotes();
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ use Friendica\Database\DBA;
|
||||||
|
|
||||||
// This file is required several times during the test in DbaDefinition which justifies this condition
|
// This file is required several times during the test in DbaDefinition which justifies this condition
|
||||||
if (!defined('DB_UPDATE_VERSION')) {
|
if (!defined('DB_UPDATE_VERSION')) {
|
||||||
define('DB_UPDATE_VERSION', 1537);
|
define('DB_UPDATE_VERSION', 1538);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -87,6 +87,49 @@
|
||||||
INNER JOIN `contact` ON `group_member`.`contact-id` = `contact`.`id`
|
INNER JOIN `contact` ON `group_member`.`contact-id` = `contact`.`id`
|
||||||
INNER JOIN `group` ON `group_member`.`gid` = `group`.`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" => [
|
"post-user-view" => [
|
||||||
"fields" => [
|
"fields" => [
|
||||||
"id" => ["post-user", "id"],
|
"id" => ["post-user", "id"],
|
||||||
|
|
Loading…
Reference in a new issue