Merge pull request #96 from Poniverse/postgres

The switch to PostgreSQL
This commit is contained in:
Josef Citrine 2016-07-18 00:59:40 +01:00 committed by GitHub
commit 52cdf621b3
117 changed files with 2646 additions and 267 deletions

View file

@ -67,7 +67,7 @@ class AddTrackToPlaylistCommand extends CommandBase
} }
$songIndex = $this->_playlist->tracks()->count() + 1; $songIndex = $this->_playlist->trackCount() + 1;
$this->_playlist->tracks()->attach($this->_track, ['position' => $songIndex]); $this->_playlist->tracks()->attach($this->_track, ['position' => $songIndex]);
$this->_playlist->touch(); $this->_playlist->touch();

View file

@ -63,7 +63,6 @@ class EditAlbumCommand extends CommandBase
'title' => 'required|min:3|max:50', 'title' => 'required|min:3|max:50',
'cover' => 'image|mimes:png|min_width:350|min_height:350', 'cover' => 'image|mimes:png|min_width:350|min_height:350',
'cover_id' => 'exists:images,id', 'cover_id' => 'exists:images,id',
'track_ids' => 'exists:tracks,id',
'username' => 'exists:users,username' 'username' => 'exists:users,username'
]; ];
@ -73,6 +72,14 @@ class EditAlbumCommand extends CommandBase
return CommandResponse::fail($validator); return CommandResponse::fail($validator);
} }
$trackIds = explode(',', $this->_input['track_ids']);
$trackIdsCount = count($trackIds);
$trackDbCount = DB::table('tracks')->whereIn('id', $trackIds)->count();
if ($trackDbCount != $trackIdsCount) {
return CommandResponse::fail("Track IDs invalid");
}
$this->_album->title = $this->_input['title']; $this->_album->title = $this->_input['title'];
$this->_album->description = $this->_input['description']; $this->_album->description = $this->_input['description'];

View file

@ -80,7 +80,7 @@ class ParseTrackTagsCommand extends CommandBase
if ($this->track->album_id === null) { if ($this->track->album_id === null) {
$this->track->track_number = null; $this->track->track_number = null;
} else { } else {
$this->track->track_number = $this->input['track_number'] ?? $parsedTags['track_number']; $this->track->track_number = filter_var($this->input['track_number'] ?? $parsedTags['track_number'], FILTER_SANITIZE_NUMBER_INT);
} }
$this->track->released_at = isset($this->input['released_at']) $this->track->released_at = isset($this->input['released_at'])
@ -95,10 +95,30 @@ class ParseTrackTagsCommand extends CommandBase
$this->track->is_downloadable = $this->input['is_downloadable'] ?? true; $this->track->is_downloadable = $this->input['is_downloadable'] ?? true;
$this->track->is_listed = $this->input['is_listed'] ?? true; $this->track->is_listed = $this->input['is_listed'] ?? true;
$this->track = $this->unsetNullVariables($this->track);
$this->track->save(); $this->track->save();
return CommandResponse::succeed(); return CommandResponse::succeed();
} }
/**
* If a value is null, remove it! Helps prevent weird SQL errors
*
* @param Track
* @return Track
*/
private function unsetNullVariables($track) {
$vars = $track->getAttributes();
foreach ($vars as $key => $value) {
if ($value == null) {
unset($track->{"$key"});
}
}
return $track;
}
/** /**
* Returns the ID of the given genre, creating it if necessary. * Returns the ID of the given genre, creating it if necessary.
* *
@ -340,7 +360,7 @@ class ParseTrackTagsCommand extends CommandBase
} elseif (isset($tags['creation_date'])) { } elseif (isset($tags['creation_date'])) {
$releaseDate = $this->parseDateString($tags['creation_date'][0]); $releaseDate = $this->parseDateString($tags['creation_date'][0]);
} else { } else {
$releaseDate = 0; $releaseDate = null;
} }
return [ return [

View file

@ -49,7 +49,7 @@ class ToggleFavouriteCommand extends CommandBase
return $user != null; return $user != null;
} }
private function getEntityBeingFavourited():Favouritable private function getEntityBeingFavourited():Favouritable
{ {
switch ($this->_resourceType) { switch ($this->_resourceType) {
@ -80,10 +80,9 @@ class ToggleFavouriteCommand extends CommandBase
$fav = new Favourite(); $fav = new Favourite();
$fav->$typeId = $this->_resourceId; $fav->$typeId = $this->_resourceId;
$fav->user_id = Auth::user()->id; $fav->user_id = Auth::user()->id;
$fav->created_at = time();
$fav->save(); $fav->save();
$isFavourited = true; $isFavourited = true;
Notification::newFavourite($this->getEntityBeingFavourited(), $fav->user); Notification::newFavourite($this->getEntityBeingFavourited(), $fav->user);
} }

View file

@ -62,10 +62,9 @@ class ToggleFollowingCommand extends CommandBase
$follow = new Follower(); $follow = new Follower();
$follow->$typeId = $this->_resourceId; $follow->$typeId = $this->_resourceId;
$follow->user_id = Auth::user()->id; $follow->user_id = Auth::user()->id;
$follow->created_at = time();
$follow->save(); $follow->save();
$isFollowed = true; $isFollowed = true;
Notification::newFollower($follow->artist, Auth::user()); Notification::newFollower($follow->artist, Auth::user());
} }

View file

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

View file

@ -213,12 +213,13 @@ class ArtistsController extends ApiControllerBase
$page = Input::get('page'); $page = Input::get('page');
} }
$query = User::orderBy('display_name', 'asc') $query = User::where('track_count', '>', 0);
->where('track_count', '>', 0);
$count = $query->count(); $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); $query->skip(($page - 1) * $perPage)->take($perPage);
$users = []; $users = [];

View file

@ -81,11 +81,10 @@ class PlaylistsController extends ApiControllerBase
->where('track_count', '>', 1) ->where('track_count', '>', 1)
->whereIsPublic(true); ->whereIsPublic(true);
$this->applyFilters($query);
$count = $query->count(); $count = $query->count();
$perPage = 40; $this->applyOrdering($query);
$perPage = 40;
$query->skip(($page - 1) * $perPage)->take($perPage); $query->skip(($page - 1) * $perPage)->take($perPage);
$playlists = []; $playlists = [];
@ -211,7 +210,16 @@ class PlaylistsController extends ApiControllerBase
return Response::json($playlists, 200); 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')) { if (Input::has('order')) {
$order = \Input::get('order'); $order = \Input::get('order');

View file

@ -33,17 +33,17 @@ use Carbon\Carbon;
class StatsController extends ApiControllerBase class StatsController extends ApiControllerBase
{ {
private function getStatsData($id, $hourly = false) { private function getStatsData($id, $hourly = false) {
$playRange = "1 MONTH"; $playRange = "'1 MONTH'";
if ($hourly) { if ($hourly) {
$playRange = "2 DAY"; $playRange = "'2 DAY'";
} }
$statQuery = DB::table('resource_log_items') $statQuery = DB::table('resource_log_items')
->selectRaw('created_at, COUNT(1) AS `plays`') ->selectRaw('created_at, COUNT(1) AS "plays"')
->where('track_id', '=', $id) ->where('track_id', '=', $id)
->where('log_type', '=', ResourceLogItem::PLAY) ->where('log_type', '=', ResourceLogItem::PLAY)
->whereRaw('`created_at` > now() - INTERVAL '.$playRange) ->whereRaw('"created_at" > now() - INTERVAL '.$playRange)
->groupBy('created_at') ->groupBy('created_at')
->orderBy('created_at') ->orderBy('created_at')
->get(); ->get();

View file

@ -156,8 +156,9 @@ class TracksController extends ApiControllerBase
} }
$this->applyFilters($query); $this->applyFilters($query);
$totalCount = $query->count(); $totalCount = $query->count();
$this->applyOrdering($query);
$query->take($perPage)->skip($perPage * ($page - 1)); $query->take($perPage)->skip($perPage * ($page - 1));
$tracks = []; $tracks = [];
@ -205,7 +206,15 @@ class TracksController extends ApiControllerBase
return Response::json(Track::mapPrivateTrackShow($track), 200); 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')) { if (Input::has('order')) {
$order = \Input::get('order'); $order = \Input::get('order');
@ -213,6 +222,17 @@ class TracksController extends ApiControllerBase
$query->orderBy($parts[0], $parts[1]); $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')) { if (Input::has('is_vocal')) {
$isVocal = \Input::get('is_vocal'); $isVocal = \Input::get('is_vocal');
if ($isVocal == 'true') { if ($isVocal == 'true') {

View file

@ -204,13 +204,23 @@ class Playlist extends Model implements Searchable, Commentable, Favouritable
]; ];
} }
public function tracks() public function tracks(bool $ordered = true)
{ {
return $this $query = $this
->belongsToMany(Track::class) ->belongsToMany(Track::class)
->withPivot('position') ->withPivot('position')
->withTimestamps() ->withTimestamps();
->orderBy('position', 'asc');
if ($ordered) {
$query = $query->orderBy('position', 'asc');
}
return $query;
}
public function trackCount():int
{
return $this->tracks(false)->count();
} }
public function trackFiles() public function trackFiles()
@ -233,7 +243,7 @@ class Playlist extends Model implements Searchable, Commentable, Favouritable
{ {
return $this->hasMany(PinnedPlaylist::class); return $this->hasMany(PinnedPlaylist::class);
} }
public function favourites():HasMany { public function favourites():HasMany {
return $this->hasMany(Favourite::class); return $this->hasMany(Favourite::class);
} }

View file

@ -39,7 +39,7 @@ class ShowSong extends Model
public function trackCountRelation() { public function trackCountRelation() {
return $this->belongsToMany(Track::class) return $this->belongsToMany(Track::class)
->select(['show_song_id', DB::raw('count(*) as track_count')]) ->select(['show_song_id', DB::raw('count(*) as track_count')])
->groupBy('show_song_id'); ->groupBy('show_song_id', 'track_id');
} }
public function tracks(){ public function tracks(){

View file

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

View file

@ -30,7 +30,9 @@
}, },
"autoload": { "autoload": {
"classmap": [ "classmap": [
"database", "database/factories",
"database/migrations",
"database/seeds",
"app/Library" "app/Library"
], ],
"psr-4": { "psr-4": {

565
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -26,7 +26,8 @@ return [
| |
*/ */
'default' => env('DB_CONNECTION', 'mysql'), //'mysql' => env('DB_CONNECTION', 'mysql'),
'default' => env('DB_CONNECTION', 'pgsql'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -72,10 +73,10 @@ return [
'pgsql' => [ 'pgsql' => [
'driver' => 'pgsql', 'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'), 'host' => env('POSTGRESQL_DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'), 'database' => env('POSTGRESQL_DB_DATABASE', 'homestead'),
'username' => env('DB_USERNAME', 'forge'), 'username' => env('POSTGRESQL_DB_USERNAME', 'homestead'),
'password' => env('DB_PASSWORD', ''), 'password' => env('POSTGRESQL_DB_PASSWORD', 'secret'),
'charset' => 'utf8', 'charset' => 'utf8',
'prefix' => '', 'prefix' => '',
'schema' => 'public', 'schema' => 'public',

38
database/after-import.sql Normal file
View file

@ -0,0 +1,38 @@
ALTER TABLE users ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone, ALTER bio SET DEFAULT '';
ALTER TABLE tracks ALTER created_at TYPE timestamp(0) without time zone,
ALTER updated_at TYPE timestamp(0) without time zone,
ALTER deleted_at TYPE timestamp(0) without time zone,
ALTER published_at TYPE timestamp(0) without time zone,
ALTER released_at TYPE timestamp(0) without time zone,
ALTER license_id DROP NOT NULL,
ALTER genre_id DROP NOT NULL,
ALTER track_type_id DROP NOT NULL,
ALTER description DROP NOT NULL,
ALTER lyrics DROP NOT NULL,
ALTER cover_id DROP NOT NULL,
ALTER album_id DROP NOT NULL,
ALTER track_number DROP NOT NULL,
ALTER hash DROP NOT NULL,
ALTER metadata DROP NOT NULL,
ALTER original_tags DROP NOT NULL,
ALTER is_vocal SET DEFAULT false,
ALTER is_explicit SET DEFAULT false,
ALTER is_downloadable SET DEFAULT false,
ALTER view_count SET DEFAULT 0,
ALTER play_count SET DEFAULT 0,
ALTER download_count SET DEFAULT 0,
ALTER favourite_count SET DEFAULT 0,
ALTER comment_count SET DEFAULT 0,
ALTER is_latest SET DEFAULT false,
ALTER is_listed SET DEFAULT true;
ALTER TABLE track_files ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone;
ALTER TABLE images ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone;
ALTER TABLE genres ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone;
ALTER TABLE resource_users ALTER is_followed SET DEFAULT false, ALTER is_favourited SET DEFAULT false, ALTER is_pinned SET DEFAULT false, ALTER view_count SET DEFAULT 0, ALTER play_count SET DEFAULT 0, ALTER download_count SET DEFAULT 0;
ALTER TABLE comments ALTER ip_address DROP NOT NULL, ALTER profile_id DROP NOT NULL, ALTER track_id DROP NOT NULL, ALTER album_id DROP NOT NULL, ALTER playlist_id DROP NOT NULL, ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone, ALTER deleted_at TYPE timestamp(0) without time zone;
ALTER TABLE playlists ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone, ALTER deleted_at TYPE timestamp(0) without time zone, ALTER track_count SET DEFAULT 0, ALTER view_count SET DEFAULT 0, ALTER download_count SET DEFAULT 0, ALTER favourite_count SET DEFAULT 0, ALTER follow_count SET DEFAULT 0, ALTER comment_count SET DEFAULT 0;
ALTER TABLE playlist_track ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone;
ALTER TABLE albums ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone, ALTER deleted_at TYPE timestamp(0) without time zone;
ALTER TABLE show_songs ALTER created_at TYPE timestamp(0) without time zone, ALTER updated_at TYPE timestamp(0) without time zone, ALTER deleted_at TYPE timestamp(0) without time zone;

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateActivitiesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('activities', function(Blueprint $table)
{
$table->bigInteger('id', true)->unsigned();
$table->dateTime('created_at')->index();
$table->integer('user_id')->unsigned();
$table->unsignedTinyInteger('activity_type');
$table->unsignedTinyInteger('resource_type');
$table->integer('resource_id')->unsigned();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('activities');
}
}

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateAlbumsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('albums', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index('albums_user_id_foreign');
$table->string('title')->index();
$table->string('slug')->index();
$table->text('description', 65535);
$table->integer('cover_id')->unsigned()->nullable()->index('albums_cover_id_foreign');
$table->integer('track_count')->unsigned()->default(0);
$table->integer('view_count')->unsigned()->default(0);
$table->integer('download_count')->unsigned()->default(0);
$table->integer('favourite_count')->unsigned()->default(0);
$table->integer('comment_count')->unsigned()->default(0);
$table->timestamps();
$table->softDeletes()->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('albums');
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateCacheTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cache', function(Blueprint $table)
{
$table->string('key')->index();
$table->text('value', 65535);
$table->integer('expiration')->unsigned()->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('cache');
}
}

View file

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateCommentsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('comments', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index('comments_user_id_foreign');
$table->string('ip_address', 46)->nullable();
$table->text('content', 65535);
$table->timestamps();
$table->softDeletes()->index();
$table->integer('profile_id')->unsigned()->nullable()->index();
$table->integer('track_id')->unsigned()->nullable()->index();
$table->integer('album_id')->unsigned()->nullable()->index();
$table->integer('playlist_id')->unsigned()->nullable()->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('comments');
}
}

View file

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateFailedJobsTable2
*
* This is the PostgreSQL version of CreateFailedJobsTable.
*/
class CreateFailedJobsTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('failed_jobs', function(Blueprint $table)
{
$table->increments('id');
$table->text('connection', 65535);
$table->text('queue', 65535);
$table->text('payload');
$table->dateTime('failed_at')->default('now()');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('failed_jobs');
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateFavouritesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('favourites', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('track_id')->unsigned()->nullable()->index();
$table->integer('album_id')->unsigned()->nullable()->index();
$table->integer('playlist_id')->unsigned()->nullable()->index();
$table->dateTime('created_at')->default('now()')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('favourites');
}
}

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateFollowersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('followers', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('artist_id')->unsigned()->nullable()->index();
$table->integer('playlist_id')->unsigned()->nullable()->index();
$table->dateTime('created_at')->default('now()')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('followers');
}
}

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateGenresTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('genres', function(Blueprint $table)
{
$table->increments('id');
$table->string('name')->unique();
$table->string('slug', 200)->index();
$table->softDeletes()->index();
$table->nullableTimestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('genres');
}
}

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateImagesTable2
*
* This is the PostgreSQL version of CreateImagesTable.
*/
class CreateImagesTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('images', function(Blueprint $table)
{
$table->increments('id');
$table->string('filename', 256);
$table->string('mime', 100);
$table->string('extension', 32);
$table->unsignedInteger('size');
$table->string('hash', 32)->index();
$table->unsignedInteger('uploaded_by')->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('images');
}
}

View file

@ -0,0 +1,73 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateLicensesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('licenses', function(Blueprint $table)
{
$table->increments('id');
$table->string('title', 100);
$table->text('description', 65535);
$table->boolean('affiliate_distribution');
$table->boolean('open_distribution');
$table->boolean('remix');
});
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
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('licenses');
}
}

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateMlpmaTracksTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mlpma_tracks', function(Blueprint $table)
{
$table->increments('id');
$table->integer('track_id')->unsigned()->index();
$table->string('path')->index();
$table->string('filename')->index();
$table->string('extension')->index();
$table->dateTime('imported_at');
$table->text('parsed_tags');
$table->text('raw_tags');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('mlpma_tracks');
}
}

View file

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateNewsTable2
*
* This is the PostgreSQL version of CreateNewsTable.
*/
class CreateNewsTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('news', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->string('post_hash', 32)->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('news');
}
}

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateNotificationsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('notifications', function(Blueprint $table)
{
$table->bigInteger('id', true)->unsigned();
$table->bigInteger('activity_id')->unsigned()->index();
$table->integer('user_id')->unsigned()->index();
$table->boolean('is_read')->default(false)->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('notifications');
}
}

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateOauth2TokensTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('oauth2_tokens', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('external_user_id')->unsigned();
$table->text('access_token', 65535);
$table->dateTime('expires')->default('now()');
$table->text('refresh_token', 65535);
$table->string('type');
$table->string('service');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('oauth2_tokens');
}
}

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreatePinnedPlaylistsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('pinned_playlists', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('playlist_id')->unsigned()->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('pinned_playlists');
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreatePlaylistTrackTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('playlist_track', function(Blueprint $table)
{
$table->increments('id');
$table->timestamps();
$table->integer('playlist_id')->unsigned()->index();
$table->integer('track_id')->unsigned()->index();
$table->integer('position')->unsigned();
$table->unique(['playlist_id','track_id']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('playlist_track');
}
}

View file

@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreatePlaylistsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('playlists', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->string('title')->index();
$table->string('slug');
$table->text('description', 65535);
$table->boolean('is_public')->index();
$table->integer('track_count')->unsigned()->default(0)->index();
$table->integer('view_count')->unsigned()->default(0);
$table->integer('download_count')->unsigned()->default(0);
$table->integer('favourite_count')->unsigned()->default(0);
$table->integer('follow_count')->unsigned()->default(0);
$table->integer('comment_count')->unsigned()->default(0);
$table->timestamps();
$table->date('deleted_at')->nullable()->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('playlists');
}
}

View file

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateResourceLogItemsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('resource_log_items', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable()->index();
$table->tinyInteger('log_type')->unsigned();
$table->string('ip_address', 46)->index();
$table->tinyInteger('track_format_id')->unsigned()->nullable();
$table->integer('track_id')->unsigned()->nullable()->index();
$table->integer('album_id')->unsigned()->nullable()->index();
$table->integer('playlist_id')->unsigned()->nullable()->index();
$table->dateTime('created_at')->default('now()');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('resource_log_items');
}
}

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateResourceUsersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('resource_users', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('track_id')->unsigned()->nullable()->index();
$table->integer('album_id')->unsigned()->nullable()->index();
$table->integer('playlist_id')->unsigned()->nullable()->index();
$table->integer('artist_id')->unsigned()->nullable()->index();
$table->boolean('is_followed')->default(false);
$table->boolean('is_favourited')->default(false);
$table->boolean('is_pinned')->default(false);
$table->unsignedInteger('view_count')->default(0);
$table->unsignedInteger('play_count')->default(0);
$table->unsignedInteger('download_count')->default(0);
$table->unique(['user_id','track_id','album_id','playlist_id','artist_id'], 'resource_unique');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('resource_users');
}
}

View file

@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateRevisionsTable2
*
* This is the PostgreSQL version of CreateRevisionsTable.
*/
class CreateRevisionsTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('revisions', function(Blueprint $table)
{
$table->increments('id');
$table->string('revisionable_type');
$table->integer('revisionable_id');
$table->unsignedInteger('user_id')->nullable();
$table->string('key');
$table->text('old_value', 65535)->nullable();
$table->text('new_value', 65535)->nullable();
$table->timestamps();
$table->index(['revisionable_id','revisionable_type']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('revisions');
}
}

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateRoleUserTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('role_user', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('role_id')->unsigned()->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('role_user');
}
}

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateRolesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
});
DB::table('roles')->insert(['name' => 'super_admin']);
DB::table('roles')->insert(['name' => 'admin']);
DB::table('roles')->insert(['name' => 'moderator']);
DB::table('roles')->insert(['name' => 'user']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('roles');
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateSessionsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('sessions', function(Blueprint $table)
{
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('sessions');
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateShowSongTrackTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('show_song_track', function(Blueprint $table)
{
$table->increments('id');
$table->integer('track_id')->unsigned()->index('show_song_track_track_id_foreign');
$table->integer('show_song_id')->unsigned()->index('show_song_track_show_song_id_foreign');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('show_song_track');
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateShowSongsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('show_songs', function(Blueprint $table)
{
$table->increments('id');
$table->string('title', 100)->index('show_songs_title_fulltext');
$table->text('lyrics', 65535);
$table->string('slug', 200);
$table->timestamps();
$table->timestamp('deleted_at')->default(DB::raw('CURRENT_TIMESTAMP'));
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('show_songs');
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateSubscriptionsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('subscriptions', function(Blueprint $table)
{
$table->bigInteger('id', true)->unsigned();
$table->integer('user_id')->unsigned()->index();
$table->string('endpoint');
$table->string('p256dh');
$table->string('auth');
$table->nullableTimestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('subscriptions');
}
}

View file

@ -0,0 +1,45 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateTrackFilesTable2
*
* This is the PostgreSQL version of CreateTrackFilesTable.
*/
class CreateTrackFilesTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('track_files', function(Blueprint $table)
{
$table->increments('id');
$table->integer('track_id')->unsigned()->index('track_files_track_id_foreign');
$table->boolean('is_master')->default(false)->index();
$table->string('format')->index();
$table->timestamps();
$table->boolean('is_cacheable')->default(false)->index();
$table->unsignedTinyInteger('status')->default(false);
$table->dateTime('expires_at')->nullable()->index();
$table->integer('filesize')->unsigned()->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('track_files');
}
}

View file

@ -0,0 +1,70 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateTrackTypesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('track_types', function(Blueprint $table)
{
$table->increments('id');
$table->string('title');
$table->string('editor_title');
});
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()
{
Schema::drop('track_types');
}
}

View file

@ -0,0 +1,67 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateTracksTable2
*
* This is the PostgreSQL version of CreateTracksTable.
*/
class CreateTracksTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('tracks', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned()->index('tracks_user_id_foreign');
$table->integer('license_id')->unsigned()->nullable()->index('tracks_license_id_foreign');
$table->integer('genre_id')->unsigned()->nullable()->index();
$table->integer('track_type_id')->unsigned()->nullable()->index('tracks_track_type_id_foreign');
$table->string('title', 100)->index();
$table->string('slug', 200)->index();
$table->text('description', 65535)->nullable();
$table->text('lyrics', 65535)->nullable();
$table->boolean('is_vocal')->default(0);
$table->boolean('is_explicit')->default(0);
$table->integer('cover_id')->unsigned()->nullable()->index('tracks_cover_id_foreign');
$table->boolean('is_downloadable')->default(0);
$table->float('duration')->unsigned();
$table->integer('play_count')->unsigned()->default(0);
$table->integer('view_count')->unsigned()->default(0);
$table->integer('download_count')->unsigned()->default(0);
$table->integer('favourite_count')->unsigned()->default(0);
$table->integer('comment_count')->unsigned()->default(0);
$table->timestamps();
$table->softDeletes()->index();
$table->dateTime('published_at')->nullable()->index();
$table->dateTime('released_at')->nullable();
$table->integer('album_id')->unsigned()->nullable()->index('tracks_album_id_foreign');
$table->integer('track_number')->unsigned()->nullable();
$table->boolean('is_latest')->default(0);
$table->string('hash', 32)->nullable();
$table->boolean('is_listed')->default(1);
$table->string('source', 40)->default('direct_upload');
$table->jsonb('metadata')->nullable();
$table->jsonb('original_tags')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('tracks');
}
}

View file

@ -0,0 +1,53 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
/**
* Class CreateUsersTable2
*
* This is the PostgreSQL version of CreateUsersTable.
*/
class CreateUsersTable2 extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('display_name')->index();
$table->string('username')->nullable();
$table->boolean('sync_names')->default(true);
$table->string('email', 150)->nullable();
$table->string('gravatar')->nullable();
$table->string('slug')->unique();
$table->boolean('uses_gravatar')->default(true);
$table->boolean('can_see_explicit_content')->default(false);
$table->text('bio', 65535)->default('');
$table->integer('track_count')->unsigned()->default(0)->index();
$table->integer('comment_count')->unsigned()->default(0);
$table->timestamps();
$table->integer('avatar_id')->unsigned()->nullable()->index('users_avatar_id_foreign');
$table->string('remember_token', 100)->nullable();
$table->boolean('is_archived')->default(false)->index();
$table->dateTime('disabled_at')->nullable()->index();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
}

View file

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddForeignKeysToAlbumsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('albums', function(Blueprint $table)
{
$table->foreign('cover_id')->references('id')->on('images')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('albums', function(Blueprint $table)
{
$table->dropForeign('albums_cover_id_foreign');
$table->dropForeign('albums_user_id_foreign');
});
}
}

View file

@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddForeignKeysToCommentsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('comments', function(Blueprint $table)
{
$table->foreign('album_id')->references('id')->on('albums')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('playlist_id')->references('id')->on('playlists')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('profile_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('track_id')->references('id')->on('tracks')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('comments', function(Blueprint $table)
{
$table->dropForeign('comments_album_id_foreign');
$table->dropForeign('comments_playlist_id_foreign');
$table->dropForeign('comments_profile_id_foreign');
$table->dropForeign('comments_track_id_foreign');
$table->dropForeign('comments_user_id_foreign');
});
}
}

View file

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddForeignKeysToFavouritesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('favourites', function(Blueprint $table)
{
$table->foreign('album_id')->references('id')->on('albums')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('playlist_id')->references('id')->on('playlists')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('track_id')->references('id')->on('tracks')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('favourites', function(Blueprint $table)
{
$table->dropForeign('favourites_album_id_foreign');
$table->dropForeign('favourites_playlist_id_foreign');
$table->dropForeign('favourites_track_id_foreign');
$table->dropForeign('favourites_user_id_foreign');
});
}
}

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddForeignKeysToFollowersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('followers', function(Blueprint $table)
{
$table->foreign('artist_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('playlist_id')->references('id')->on('playlists')->onUpdate('RESTRICT')->onDelete('RESTRICT');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('followers', function(Blueprint $table)
{
$table->dropForeign('followers_artist_id_foreign');
$table->dropForeign('followers_playlist_id_foreign');
$table->dropForeign('followers_user_id_foreign');
});
}
}

View file

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddForeignKeysToImagesTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('images', function(Blueprint $table)
{
$table->foreign('uploaded_by')->references('id')->on('users')->onUpdate('RESTRICT')->onDelete('RESTRICT');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('images', function(Blueprint $table)
{
$table->dropForeign('images_uploaded_by_foreign');
});
}
}

Some files were not shown because too many files have changed in this diff Show more