mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-19 04:51:17 +00:00
fix: add downloads_count to episodes table, computed every hour
This removes computing latency when retrieving episodes list with download count in admin. The more analytics records, the more it took to calculate the sum of hits to get the downloads count for each episode.
This commit is contained in:
parent
f288a750f5
commit
f981937645
50
app/Commands/EpisodesComputeDownloads.php
Normal file
50
app/Commands/EpisodesComputeDownloads.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Commands;
|
||||
|
||||
use App\Models\EpisodeModel;
|
||||
use CodeIgniter\CLI\BaseCommand;
|
||||
|
||||
class EpisodesComputeDownloads extends BaseCommand
|
||||
{
|
||||
/**
|
||||
* The Command's Group
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $group = 'Episodes';
|
||||
|
||||
/**
|
||||
* The Command's Name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'episodes:compute-downloads';
|
||||
|
||||
/**
|
||||
* The Command's Description
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = "Calculates all episodes downloads and stores results in episodes' downloads_count field.";
|
||||
|
||||
/**
|
||||
* Actually execute a command.
|
||||
*/
|
||||
public function run(array $params): void
|
||||
{
|
||||
$episodesModel = new EpisodeModel();
|
||||
$query = $episodesModel->builder()
|
||||
->select('episodes.id as id, IFNULL(SUM(ape.hits),0) as downloads_count')
|
||||
->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left')
|
||||
->groupBy('episodes.id');
|
||||
|
||||
$episodeModel2 = new EpisodeModel();
|
||||
$episodeModel2->builder()
|
||||
->setQueryAsData($query)
|
||||
->onConstraint('id')
|
||||
->updateBatch();
|
||||
}
|
||||
}
|
@ -51,5 +51,9 @@ class Tasks extends BaseConfig
|
||||
$schedule->command('podcast:import')
|
||||
->everyMinute()
|
||||
->named('podcast-import');
|
||||
|
||||
$schedule->command('episodes:compute-downloads')
|
||||
->everyHour()
|
||||
->named('episodes:compute-downloads');
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Database\Migrations;
|
||||
|
||||
use CodeIgniter\Database\Migration;
|
||||
|
||||
class AddEpisodeDownloadsCount extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$fields = [
|
||||
'downloads_count' => [
|
||||
'type' => 'INT',
|
||||
'unsigned' => true,
|
||||
'default' => 0,
|
||||
'after' => 'is_published_on_hubs',
|
||||
],
|
||||
];
|
||||
|
||||
$this->forge->addColumn('episodes', $fields);
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->forge->dropColumn('episodes', 'downloads_count');
|
||||
}
|
||||
}
|
@ -72,9 +72,9 @@ use RuntimeException;
|
||||
* @property string|null $location_geo
|
||||
* @property string|null $location_osm
|
||||
* @property bool $is_published_on_hubs
|
||||
* @property int $downloads_count
|
||||
* @property int $posts_count
|
||||
* @property int $comments_count
|
||||
* @property int $downloads
|
||||
* @property EpisodeComment[]|null $comments
|
||||
* @property bool $is_premium
|
||||
* @property int $created_by
|
||||
@ -112,8 +112,6 @@ class Episode extends Entity
|
||||
|
||||
protected ?Chapters $chapters = null;
|
||||
|
||||
protected int $downloads = 0;
|
||||
|
||||
/**
|
||||
* @var Person[]|null
|
||||
*/
|
||||
@ -171,6 +169,7 @@ class Episode extends Entity
|
||||
'location_geo' => '?string',
|
||||
'location_osm' => '?string',
|
||||
'is_published_on_hubs' => 'boolean',
|
||||
'downloads_count' => 'integer',
|
||||
'posts_count' => 'integer',
|
||||
'comments_count' => 'integer',
|
||||
'is_premium' => 'boolean',
|
||||
|
@ -88,6 +88,7 @@ class EpisodeModel extends UuidModel
|
||||
'location_geo',
|
||||
'location_osm',
|
||||
'is_published_on_hubs',
|
||||
'downloads_count',
|
||||
'posts_count',
|
||||
'comments_count',
|
||||
'is_premium',
|
||||
|
@ -70,34 +70,25 @@ class EpisodeController extends BaseController
|
||||
// Use LIKE operator as a fallback.
|
||||
if (strlen($query) < 4) {
|
||||
$episodes = $episodeModel
|
||||
->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads')
|
||||
->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left')
|
||||
->where('episodes.podcast_id', $podcast->id)
|
||||
->where('podcast_id', $podcast->id)
|
||||
->like('title', $episodeModel->db->escapeLikeString($query))
|
||||
->orLike('description_markdown', $episodeModel->db->escapeLikeString($query))
|
||||
->orLike('slug', $episodeModel->db->escapeLikeString($query))
|
||||
->orLike('location_name', $episodeModel->db->escapeLikeString($query))
|
||||
->groupBy('episodes.id')
|
||||
->orderBy('-`published_at`', '', false)
|
||||
->orderBy('created_at', 'desc');
|
||||
} else {
|
||||
$episodes = $episodeModel
|
||||
->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads')
|
||||
->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left')
|
||||
->where('episodes.podcast_id', $podcast->id)
|
||||
->where('podcast_id', $podcast->id)
|
||||
->where(
|
||||
"MATCH (title, description_markdown, slug, location_name) AGAINST ('{$episodeModel->db->escapeString(
|
||||
$query
|
||||
)}')"
|
||||
)
|
||||
->groupBy('episodes.id');
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$episodes = $episodeModel
|
||||
->select('episodes.*, IFNULL(SUM(ape.hits),0) as downloads')
|
||||
->join('analytics_podcasts_by_episode ape', 'episodes.id=ape.episode_id', 'left')
|
||||
->where('episodes.podcast_id', $podcast->id)
|
||||
->groupBy('episodes.id')
|
||||
->where('podcast_id', $podcast->id)
|
||||
->orderBy('-`published_at`', '', false)
|
||||
->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ data_table(
|
||||
[
|
||||
'header' => lang('Episode.list.downloads'),
|
||||
'cell' => function ($episode): string {
|
||||
return downloads_abbr($episode->downloads);
|
||||
return downloads_abbr($episode->downloads_count);
|
||||
},
|
||||
],
|
||||
[
|
||||
|
Loading…
x
Reference in New Issue
Block a user