#86: Modified a bunch of queries to work in PostgreSQL.

This commit is contained in:
Peter Deltchev 2016-06-26 19:20:10 -07:00
parent d4aa08b328
commit 6e8a9b34c6
8 changed files with 170 additions and 22 deletions

View file

@ -340,7 +340,7 @@ class ParseTrackTagsCommand extends CommandBase
} elseif (isset($tags['creation_date'])) {
$releaseDate = $this->parseDateString($tags['creation_date'][0]);
} else {
$releaseDate = 0;
$releaseDate = null;
}
return [

View file

@ -128,14 +128,16 @@ class AlbumsController extends ApiControllerBase
$query = Album::summary()
->with('user', 'user.avatar', 'cover')
->userDetails()
->orderBy('title', 'asc')
// An album with only one track is not really an album.
->where('track_count', '>', 1);
$count = $query->count();
$perPage = 40;
$query->skip(($page - 1) * $perPage)->take($perPage);
$query
->orderBy('title', 'asc')
->skip(($page - 1) * $perPage)
->take($perPage);
$albums = [];
foreach ($query->get() as $album) {

View file

@ -213,12 +213,13 @@ class ArtistsController extends ApiControllerBase
$page = Input::get('page');
}
$query = User::orderBy('display_name', 'asc')
->where('track_count', '>', 0);
$query = User::where('track_count', '>', 0);
$count = $query->count();
$perPage = 40;
// The query results are ordered after they're counted
// due to Postgres's behaviour when combining those two operations.
$query->orderBy('display_name', 'asc');
$perPage = 40;
$query->skip(($page - 1) * $perPage)->take($perPage);
$users = [];

View file

@ -81,11 +81,10 @@ class PlaylistsController extends ApiControllerBase
->where('track_count', '>', 1)
->whereIsPublic(true);
$this->applyFilters($query);
$count = $query->count();
$perPage = 40;
$this->applyOrdering($query);
$perPage = 40;
$query->skip(($page - 1) * $perPage)->take($perPage);
$playlists = [];
@ -211,7 +210,16 @@ class PlaylistsController extends ApiControllerBase
return Response::json($playlists, 200);
}
private function applyFilters($query)
/**
* This function should not deal with anything other than applying order,
* which is done after the query's total possible results are counted due
* to Postgres not allowing "ORDER BY" to be combined with "COUNT()".
*
* @param $query
* @return mixed
*/
private function applyOrdering($query)
{
if (Input::has('order')) {
$order = \Input::get('order');

View file

@ -156,8 +156,9 @@ class TracksController extends ApiControllerBase
}
$this->applyFilters($query);
$totalCount = $query->count();
$this->applyOrdering($query);
$query->take($perPage)->skip($perPage * ($page - 1));
$tracks = [];
@ -205,7 +206,15 @@ class TracksController extends ApiControllerBase
return Response::json(Track::mapPrivateTrackShow($track), 200);
}
private function applyFilters($query)
/**
* To be run after aggregating the total number of tracks for a given query.
* This is separated from applyFilters() because Postgres doesn't allow
* ORDER BY statements in a COUNT(*) query that returns a single value.
*
* @param $query
* @return mixed
*/
private function applyOrdering($query)
{
if (Input::has('order')) {
$order = \Input::get('order');
@ -213,6 +222,17 @@ class TracksController extends ApiControllerBase
$query->orderBy($parts[0], $parts[1]);
}
return $query;
}
/**
* This should be run before count()'ing a query's results.
*
* @param $query
* @return mixed
*/
private function applyFilters($query)
{
if (Input::has('is_vocal')) {
$isVocal = \Input::get('is_vocal');
if ($isVocal == 'true') {

View file

@ -272,18 +272,18 @@ class Track extends Model implements Searchable, Commentable, Favouritable
$query = static
::published()
->listed()
->join(DB::raw('
( SELECT `track_id`, `created_at`
FROM `resource_log_items`
WHERE track_id IS NOT NULL AND log_type = 3 AND `created_at` > now() - INTERVAL 1 DAY
) AS ranged_plays'),
->join(DB::raw('(
SELECT "track_id"
FROM "resource_log_items"
WHERE track_id IS NOT NULL AND log_type = 3 AND "created_at" > now() - INTERVAL \'1\' DAY
) ranged_plays'),
'tracks.id', '=', 'ranged_plays.track_id')
->groupBy('id')
->groupBy(['id', 'track_id'])
->orderBy('plays', 'desc')
->take($count);
if (!$allowExplicit) {
$query->whereIsExplicit(false);
$query->where('is_explicit', false);
}
$results = [];
@ -293,7 +293,8 @@ class Track extends Model implements Searchable, Commentable, Favouritable
}
return $results;
});
}
);
if (!count($trackIds)) {
return [];

View file

@ -23,7 +23,7 @@ class CreateUsersTable extends Migration {
$table->string('slug')->unique();
$table->boolean('uses_gravatar')->default(1);
$table->boolean('can_see_explicit_content')->default(0);
$table->text('bio', 65535);
$table->text('bio', 65535)->default('');
$table->integer('track_count')->unsigned()->default(0)->index();
$table->integer('comment_count')->unsigned()->default(0);
$table->timestamps();

View file

@ -0,0 +1,116 @@
<?php
/**
* Pony.fm - A community for pony fan music.
* Copyright (C) 2016 Peter Deltchev
*
* 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 <http://www.gnu.org/licenses/>.
*/
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class InsertStaticData extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::table('licenses')->insert([
'id' => 1,
'title' => 'Personal',
'description' => 'Only you and Pony.fm are allowed to distribute and broadcast the track.',
'affiliate_distribution' => 0,
'open_distribution' => 0,
'remix' => 0
]);
DB::table('licenses')->insert([
'id' => 2,
'title' => 'Broadcast',
'description' => 'You, Pony.fm, and its affiliates may distribute and broadcast the track.',
'affiliate_distribution' => 1,
'open_distribution' => 0,
'remix' => 0
]);
DB::table('licenses')->insert([
'id' => 3,
'title' => 'Open',
'description' => 'Anyone is permitted to broadcast and distribute the song in its original form, with attribution to you.',
'affiliate_distribution' => 1,
'open_distribution' => 1,
'remix' => 0
]);
DB::table('licenses')->insert([
'id' => 4,
'title' => 'Remix',
'description' => 'Anyone is permitted to broadcast and distribute the song in any form, or create derivative works based on it for any purpose, with attribution to you.',
'affiliate_distribution' => 1,
'open_distribution' => 1,
'remix' => 1
]);
DB::table('track_types')->insert([
'id' => 1,
'title' => 'Original Song',
'editor_title' => 'an original song'
]);
DB::table('track_types')->insert([
'id' => 2,
'title' => 'Official Song Remix',
'editor_title' => 'a remix of an official song'
]);
DB::table('track_types')->insert([
'id' => 3,
'title' => 'Fan Song Remix',
'editor_title' => 'a remix of a fan song'
]);
DB::table('track_types')->insert([
'id' => 4,
'title' => 'Ponified Song',
'editor_title' => 'a non-pony song, turned pony'
]);
DB::table('track_types')->insert([
'id' => 5,
'title' => 'Official Show Audio Remix',
'editor_title' => 'a remix of official show audio'
]);
DB::table('track_types')->insert([
'id' => 6,
'title' => 'Unclassified',
'editor_title' => 'an unclassified track'
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::table('licenses')->whereIn('id', [1, 2, 3, 4])->delete();
DB::table('track_types')->whereIn('id', [1, 2, 3, 4, 5, 6])->delete();
}
}