mirror of
https://github.com/friendica/friendica
synced 2024-12-23 04:00:15 +00:00
Merge pull request #13778 from annando/post-counts
New table "post-counts" to precalculate the counts
This commit is contained in:
commit
5b516b1dbb
9 changed files with 221 additions and 4 deletions
19
database.sql
19
database.sql
|
@ -1,6 +1,6 @@
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
-- Friendica 2024.03-dev (Yellow Archangel)
|
-- Friendica 2024.03-dev (Yellow Archangel)
|
||||||
-- DB_UPDATE_VERSION 1542
|
-- DB_UPDATE_VERSION 1543
|
||||||
-- ------------------------------------------
|
-- ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -1236,6 +1236,23 @@ CREATE TABLE IF NOT EXISTS `post-category` (
|
||||||
FOREIGN KEY (`tid`) REFERENCES `tag` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
FOREIGN KEY (`tid`) REFERENCES `tag` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT
|
||||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to categories';
|
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to categories';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TABLE post-counts
|
||||||
|
--
|
||||||
|
CREATE TABLE IF NOT EXISTS `post-counts` (
|
||||||
|
`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
|
||||||
|
`vid` smallint unsigned NOT NULL COMMENT 'Id of the verb table entry that contains the activity verbs',
|
||||||
|
`reaction` varchar(1) NOT NULL COMMENT 'Emoji Reaction',
|
||||||
|
`parent-uri-id` int unsigned COMMENT 'Id of the item-uri table that contains the parent uri',
|
||||||
|
`count` int unsigned DEFAULT 0 COMMENT 'Number of activities',
|
||||||
|
PRIMARY KEY(`uri-id`,`vid`,`reaction`),
|
||||||
|
INDEX `vid` (`vid`),
|
||||||
|
INDEX `parent-uri-id` (`parent-uri-id`),
|
||||||
|
FOREIGN KEY (`uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (`vid`) REFERENCES `verb` (`id`) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||||
|
FOREIGN KEY (`parent-uri-id`) REFERENCES `item-uri` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
|
||||||
|
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Original remote activity';
|
||||||
|
|
||||||
--
|
--
|
||||||
-- TABLE post-collection
|
-- TABLE post-collection
|
||||||
--
|
--
|
||||||
|
|
|
@ -61,6 +61,7 @@ Database Tables
|
||||||
| [post-category](help/database/db_post-category) | post relation to categories |
|
| [post-category](help/database/db_post-category) | post relation to categories |
|
||||||
| [post-collection](help/database/db_post-collection) | Collection of posts |
|
| [post-collection](help/database/db_post-collection) | Collection of posts |
|
||||||
| [post-content](help/database/db_post-content) | Content for all posts |
|
| [post-content](help/database/db_post-content) | Content for all posts |
|
||||||
|
| [post-counts](help/database/db_post-counts) | Original remote activity |
|
||||||
| [post-delivery](help/database/db_post-delivery) | Delivery data for posts for the batch processing |
|
| [post-delivery](help/database/db_post-delivery) | Delivery data for posts for the batch processing |
|
||||||
| [post-delivery-data](help/database/db_post-delivery-data) | Delivery data for items |
|
| [post-delivery-data](help/database/db_post-delivery-data) | Delivery data for items |
|
||||||
| [post-engagement](help/database/db_post-engagement) | Engagement data per post |
|
| [post-engagement](help/database/db_post-engagement) | Engagement data per post |
|
||||||
|
|
35
doc/database/db_post-counts.md
Normal file
35
doc/database/db_post-counts.md
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
Table post-counts
|
||||||
|
===========
|
||||||
|
|
||||||
|
Original remote activity
|
||||||
|
|
||||||
|
Fields
|
||||||
|
------
|
||||||
|
|
||||||
|
| Field | Description | Type | Null | Key | Default | Extra |
|
||||||
|
| ------------- | ----------------------------------------------------------- | ----------------- | ---- | --- | ------- | ----- |
|
||||||
|
| uri-id | Id of the item-uri table entry that contains the item uri | int unsigned | NO | PRI | NULL | |
|
||||||
|
| vid | Id of the verb table entry that contains the activity verbs | smallint unsigned | NO | PRI | NULL | |
|
||||||
|
| reaction | Emoji Reaction | varchar(1) | NO | PRI | NULL | |
|
||||||
|
| parent-uri-id | Id of the item-uri table that contains the parent uri | int unsigned | YES | | NULL | |
|
||||||
|
| count | Number of activities | int unsigned | YES | | 0 | |
|
||||||
|
|
||||||
|
Indexes
|
||||||
|
------------
|
||||||
|
|
||||||
|
| Name | Fields |
|
||||||
|
| ------------- | --------------------- |
|
||||||
|
| PRIMARY | uri-id, vid, reaction |
|
||||||
|
| vid | vid |
|
||||||
|
| parent-uri-id | parent-uri-id |
|
||||||
|
|
||||||
|
Foreign Keys
|
||||||
|
------------
|
||||||
|
|
||||||
|
| Field | Target Table | Target Field |
|
||||||
|
|-------|--------------|--------------|
|
||||||
|
| uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||||
|
| vid | [verb](help/database/db_verb) | id |
|
||||||
|
| parent-uri-id | [item-uri](help/database/db_item-uri) | id |
|
||||||
|
|
||||||
|
Return to [database documentation](help/database)
|
|
@ -32,6 +32,7 @@ use Friendica\Model\ItemURI;
|
||||||
use Friendica\Model\Photo;
|
use Friendica\Model\Photo;
|
||||||
use Friendica\Model\Post;
|
use Friendica\Model\Post;
|
||||||
use Friendica\Model\Post\Category;
|
use Friendica\Model\Post\Category;
|
||||||
|
use Friendica\Model\Post\Counts;
|
||||||
use Friendica\Model\Tag;
|
use Friendica\Model\Tag;
|
||||||
use Friendica\Model\Verb;
|
use Friendica\Model\Verb;
|
||||||
use Friendica\Protocol\ActivityPub\Processor;
|
use Friendica\Protocol\ActivityPub\Processor;
|
||||||
|
@ -51,7 +52,7 @@ class PostUpdate
|
||||||
// Needed for the helper function to read from the legacy term table
|
// Needed for the helper function to read from the legacy term table
|
||||||
const OBJECT_TYPE_POST = 1;
|
const OBJECT_TYPE_POST = 1;
|
||||||
|
|
||||||
const VERSION = 1507;
|
const VERSION = 1543;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the post update functions
|
* Calls the post update functions
|
||||||
|
@ -124,6 +125,9 @@ class PostUpdate
|
||||||
if (!self::update1507()) {
|
if (!self::update1507()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!self::update1543()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,4 +1307,51 @@ class PostUpdate
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create "post-counts" entries for old entries.
|
||||||
|
*
|
||||||
|
* @return bool "true" when the job is done
|
||||||
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
|
* @throws \ImagickException
|
||||||
|
*/
|
||||||
|
private static function update1543()
|
||||||
|
{
|
||||||
|
// Was the script completed?
|
||||||
|
if (DI::keyValue()->get('post_update_version') >= 1543) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = DI::keyValue()->get('post_update_version_1543_id') ?? 0;
|
||||||
|
|
||||||
|
Logger::info('Start', ['uri-id' => $id]);
|
||||||
|
|
||||||
|
$rows = 0;
|
||||||
|
|
||||||
|
$posts = Post::selectPosts(['uri-id', 'parent-uri-id'], ["`uri-id` > ? AND `gravity` IN (?, ?)", $id, Item::GRAVITY_COMMENT, Item::GRAVITY_PARENT], ['order' => ['uri-id'], 'limit' => 1000]);
|
||||||
|
|
||||||
|
if (DBA::errorNo() != 0) {
|
||||||
|
Logger::error('Database error', ['no' => DBA::errorNo(), 'message' => DBA::errorMessage()]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($post = Post::fetch($posts)) {
|
||||||
|
$id = $post['uri-id'];
|
||||||
|
Counts::updateForPost($post['uri-id'], $post['parent-uri-id']);
|
||||||
|
++$rows;
|
||||||
|
}
|
||||||
|
DBA::close($posts);
|
||||||
|
|
||||||
|
DI::keyValue()->set('post_update_version_1543_id', $id);
|
||||||
|
|
||||||
|
Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
|
||||||
|
|
||||||
|
if ($rows <= 100) {
|
||||||
|
DI::keyValue()->set('post_update_version', 1543);
|
||||||
|
Logger::info('Done');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1432,6 +1432,10 @@ class Item
|
||||||
self::updateDisplayCache($posted_item['uri-id']);
|
self::updateDisplayCache($posted_item['uri-id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_array($posted_item['gravity'], [self::GRAVITY_ACTIVITY, self::GRAVITY_COMMENT]) && ($posted_item['uid'] == 0)) {
|
||||||
|
Post\Counts::update($posted_item['thr-parent-id'], $posted_item['parent-uri-id'], $posted_item['vid'], $posted_item['verb'], $posted_item['body']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($inserted) {
|
if ($inserted) {
|
||||||
Post\Engagement::storeFromItem($posted_item);
|
Post\Engagement::storeFromItem($posted_item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Post
|
||||||
if (array_key_exists('title', $row)) {
|
if (array_key_exists('title', $row)) {
|
||||||
$row['title'] = '';
|
$row['title'] = '';
|
||||||
}
|
}
|
||||||
if (array_key_exists('body', $row)) {
|
if (array_key_exists('body', $row) && empty($row['body'])) {
|
||||||
$row['body'] = $row['verb'];
|
$row['body'] = $row['verb'];
|
||||||
}
|
}
|
||||||
if (array_key_exists('object', $row)) {
|
if (array_key_exists('object', $row)) {
|
||||||
|
|
89
src/Model/Post/Counts.php
Normal file
89
src/Model/Post/Counts.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2023, the Friendica project
|
||||||
|
*
|
||||||
|
* @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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Friendica\Model\Post;
|
||||||
|
|
||||||
|
use Friendica\Content\Smilies;
|
||||||
|
use Friendica\Database\Database;
|
||||||
|
use Friendica\Database\DBA;
|
||||||
|
use Friendica\Model\Item;
|
||||||
|
use Friendica\Model\Post;
|
||||||
|
use Friendica\Model\Verb;
|
||||||
|
use Friendica\Protocol\Activity;
|
||||||
|
|
||||||
|
class Counts
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Insert or update a post-counts entry
|
||||||
|
*
|
||||||
|
* @param int $uri_id
|
||||||
|
*/
|
||||||
|
public static function update(int $uri_id, int $parent_uri_id, int $vid, string $verb, string $body = null)
|
||||||
|
{
|
||||||
|
$condition = ['thr-parent-id' => $uri_id, 'vid' => $vid];
|
||||||
|
|
||||||
|
if ($body == $verb) {
|
||||||
|
$condition['body'] = null;
|
||||||
|
$body = '';
|
||||||
|
} elseif (($verb != Activity::POST) && (mb_strlen($body) == 1) && Smilies::isEmojiPost($body)) {
|
||||||
|
$condition['body'] = $body;
|
||||||
|
} else {
|
||||||
|
$body = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = [
|
||||||
|
'uri-id' => $uri_id,
|
||||||
|
'vid' => $vid,
|
||||||
|
'reaction' => $body,
|
||||||
|
'parent-uri-id' => $parent_uri_id,
|
||||||
|
'count' => Post::countPosts($condition),
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($fields['count'] == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DBA::insert('post-counts', $fields, Database::INSERT_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function updateForPost(int $uri_id, int $parent_uri_id)
|
||||||
|
{
|
||||||
|
self::update($uri_id, $parent_uri_id, Verb::getID(Activity::POST), Activity::POST);
|
||||||
|
|
||||||
|
$activities = DBA::p("SELECT `parent-uri-id`, `vid`, `verb`, `body` FROM `post-view` WHERE `thr-parent-id` = ? AND `gravity` = ? GROUP BY `parent-uri-id`, `vid`, `verb`, `body`", $uri_id, Item::GRAVITY_ACTIVITY);
|
||||||
|
while ($activity = DBA::fetch($activities)) {
|
||||||
|
self::update($uri_id, $activity['parent-uri-id'], $activity['vid'], $activity['verb'], $activity['body']);
|
||||||
|
}
|
||||||
|
DBA::close($activities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves counts of the given uri-id
|
||||||
|
*
|
||||||
|
* @param int $uriId
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getByURIId(int $uriId): array
|
||||||
|
{
|
||||||
|
return DBA::selectToArray('post-counts', [], ['uri-id' => $uriId]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1272,6 +1272,11 @@ class Receiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($receivers) && !empty($parent['parent-author-link'])) {
|
||||||
|
$uid = User::getIdForURL($parent['parent-author-link']);
|
||||||
|
$receivers[$uid] = ['uid' => $uid, 'type' => self::TARGET_BTO];
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($reply) && (!empty($receivers[0]) || !empty($receivers[-1]))) {
|
if (!empty($reply) && (!empty($receivers[0]) || !empty($receivers[-1]))) {
|
||||||
$parents = Post::select(['uid'], DBA::mergeConditions(['uri' => $reply], ["`uid` != ?", 0]));
|
$parents = Post::select(['uid'], DBA::mergeConditions(['uri' => $reply], ["`uid` != ?", 0]));
|
||||||
while ($parent = Post::fetch($parents)) {
|
while ($parent = Post::fetch($parents)) {
|
||||||
|
|
|
@ -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', 1542);
|
define('DB_UPDATE_VERSION', 1543);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -1264,6 +1264,21 @@ return [
|
||||||
"uid_uri-id" => ["uid", "uri-id"],
|
"uid_uri-id" => ["uid", "uri-id"],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"post-counts" => [
|
||||||
|
"comment" => "Original remote activity",
|
||||||
|
"fields" => [
|
||||||
|
"uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"],
|
||||||
|
"vid" => ["type" => "smallint unsigned", "not null" => "1", "primary" => "1", "foreign" => ["verb" => "id", "on delete" => "restrict"], "comment" => "Id of the verb table entry that contains the activity verbs"],
|
||||||
|
"reaction" => ["type" => "varchar(1)", "not null" => "1", "primary" => "1", "comment" => "Emoji Reaction"],
|
||||||
|
"parent-uri-id" => ["type" => "int unsigned", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table that contains the parent uri"],
|
||||||
|
"count" => ["type" => "int unsigned", "default" => 0, "comment" => "Number of activities"],
|
||||||
|
],
|
||||||
|
"indexes" => [
|
||||||
|
"PRIMARY" => ["uri-id", "vid", "reaction"],
|
||||||
|
"vid" => ["vid"],
|
||||||
|
"parent-uri-id" => ["parent-uri-id"],
|
||||||
|
]
|
||||||
|
],
|
||||||
"post-collection" => [
|
"post-collection" => [
|
||||||
"comment" => "Collection of posts",
|
"comment" => "Collection of posts",
|
||||||
"fields" => [
|
"fields" => [
|
||||||
|
|
Loading…
Reference in a new issue