CRUD Albums + Spotify API requests into DB.
All checks were successful
CI - Build Tonehaus Docker image / tonehaus-ci-build (push) Successful in 2m17s
All checks were successful
CI - Build Tonehaus Docker image / tonehaus-ci-build (push) Successful in 2m17s
This commit is contained in:
39
migrations/Version20251114111853.php
Normal file
39
migrations/Version20251114111853.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251114111853 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Idempotent guard: if table already exists (from previous migration), skip
|
||||
if ($schema->hasTable('albums')) {
|
||||
return;
|
||||
}
|
||||
$this->addSql('CREATE TABLE albums (id SERIAL NOT NULL, spotify_id VARCHAR(64) NOT NULL, name VARCHAR(255) NOT NULL, artists JSON NOT NULL, release_date VARCHAR(20) DEFAULT NULL, total_tracks INT NOT NULL, cover_url VARCHAR(1024) DEFAULT NULL, external_url VARCHAR(1024) DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_F4E2474FA905FC5C ON albums (spotify_id)');
|
||||
$this->addSql('COMMENT ON COLUMN albums.created_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN albums.updated_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// Be defensive: only drop the table if it exists
|
||||
if ($schema->hasTable('albums')) {
|
||||
$this->addSql('DROP TABLE albums');
|
||||
}
|
||||
}
|
||||
}
|
||||
40
migrations/Version20251114112016.php
Normal file
40
migrations/Version20251114112016.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251114112016 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE albums ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||
$this->addSql('ALTER TABLE albums ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||
$this->addSql('COMMENT ON COLUMN albums.created_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN albums.updated_at IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('ALTER INDEX uniq_album_spotify_id RENAME TO UNIQ_F4E2474FA905FC5C');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE albums ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||
$this->addSql('ALTER TABLE albums ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
|
||||
$this->addSql('COMMENT ON COLUMN albums.created_at IS NULL');
|
||||
$this->addSql('COMMENT ON COLUMN albums.updated_at IS NULL');
|
||||
$this->addSql('ALTER INDEX uniq_f4e2474fa905fc5c RENAME TO uniq_album_spotify_id');
|
||||
}
|
||||
}
|
||||
62
migrations/Version20251114113000.php
Normal file
62
migrations/Version20251114113000.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20251114113000 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Normalize reviews: add album_id FK, backfill from albums.spotify_id';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Add nullable album_id first
|
||||
$this->addSql('ALTER TABLE reviews ADD album_id INT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE reviews ADD CONSTRAINT FK_6970EF78E0C31AF9 FOREIGN KEY (album_id) REFERENCES albums (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
$this->addSql('CREATE INDEX IDX_6970EF78E0C31AF9 ON reviews (album_id)');
|
||||
|
||||
// Backfill using existing spotify_album_id if both columns exist
|
||||
// Some environments may not have the legacy column; guard with DO blocks
|
||||
$this->addSql(<<<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name='reviews' AND column_name='spotify_album_id'
|
||||
) THEN
|
||||
UPDATE reviews r
|
||||
SET album_id = a.id
|
||||
FROM albums a
|
||||
WHERE a.spotify_id = r.spotify_album_id
|
||||
AND r.album_id IS NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
SQL);
|
||||
|
||||
// Optionally set NOT NULL if all rows are linked
|
||||
$this->addSql(<<<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM reviews WHERE album_id IS NULL) THEN
|
||||
ALTER TABLE reviews ALTER COLUMN album_id SET NOT NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql('ALTER TABLE reviews DROP CONSTRAINT FK_6970EF78E0C31AF9');
|
||||
$this->addSql('DROP INDEX IF EXISTS IDX_6970EF78E0C31AF9');
|
||||
$this->addSql('ALTER TABLE reviews DROP COLUMN album_id');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
migrations/Version20251114114000.php
Normal file
45
migrations/Version20251114114000.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20251114114000 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Drop legacy duplicated review columns: spotify_album_id, album_name, album_artist';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// Guard: drop columns only if they exist
|
||||
$this->addSql(<<<'SQL'
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='reviews' AND column_name='spotify_album_id') THEN
|
||||
ALTER TABLE reviews DROP COLUMN spotify_album_id;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='reviews' AND column_name='album_name') THEN
|
||||
ALTER TABLE reviews DROP COLUMN album_name;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='reviews' AND column_name='album_artist') THEN
|
||||
ALTER TABLE reviews DROP COLUMN album_artist;
|
||||
END IF;
|
||||
END $$;
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// Recreate columns as nullable in down migration
|
||||
$this->addSql('ALTER TABLE reviews ADD spotify_album_id VARCHAR(64) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE reviews ADD album_name VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE reviews ADD album_artist VARCHAR(255) DEFAULT NULL');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
41
migrations/Version20251114120500.php
Normal file
41
migrations/Version20251114120500.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
final class Version20251114120500 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Add user-created album fields: local_id, source, created_by_id; make spotify_id nullable';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
$this->addSql("ALTER TABLE albums ADD local_id VARCHAR(64) DEFAULT NULL");
|
||||
$this->addSql("ALTER TABLE albums ADD source VARCHAR(16) NOT NULL DEFAULT 'spotify'");
|
||||
$this->addSql("ALTER TABLE albums ADD created_by_id INT DEFAULT NULL");
|
||||
$this->addSql("ALTER TABLE albums ALTER spotify_id DROP NOT NULL");
|
||||
$this->addSql("CREATE UNIQUE INDEX uniq_album_local_id ON albums (local_id)");
|
||||
$this->addSql("ALTER TABLE albums ADD CONSTRAINT FK_F4E2474FB03A8386 FOREIGN KEY (created_by_id) REFERENCES users (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE");
|
||||
$this->addSql("CREATE INDEX IDX_F4E2474FB03A8386 ON albums (created_by_id)");
|
||||
$this->addSql("UPDATE albums SET source = 'spotify' WHERE source IS NULL");
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
$this->addSql("ALTER TABLE albums DROP CONSTRAINT FK_F4E2474FB03A8386");
|
||||
$this->addSql("DROP INDEX IF EXISTS uniq_album_local_id");
|
||||
$this->addSql("DROP INDEX IF EXISTS IDX_F4E2474FB03A8386");
|
||||
$this->addSql("ALTER TABLE albums DROP COLUMN local_id");
|
||||
$this->addSql("ALTER TABLE albums DROP COLUMN source");
|
||||
$this->addSql("ALTER TABLE albums DROP COLUMN created_by_id");
|
||||
$this->addSql("ALTER TABLE albums ALTER spotify_id SET NOT NULL");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
34
migrations/Version20251120174722.php
Normal file
34
migrations/Version20251120174722.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251120174722 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE reviews ALTER album_id SET NOT NULL');
|
||||
$this->addSql('ALTER INDEX idx_6970ef78e0c31af9 RENAME TO IDX_6970EB0F1137ABCF');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE reviews ALTER album_id DROP NOT NULL');
|
||||
$this->addSql('ALTER INDEX idx_6970eb0f1137abcf RENAME TO idx_6970ef78e0c31af9');
|
||||
}
|
||||
}
|
||||
31
migrations/Version20251120175034.php
Normal file
31
migrations/Version20251120175034.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20251120175034 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user