diff --git a/.dockerignore b/.dockerignore index edf70a9..7deb771 100644 --- a/.dockerignore +++ b/.dockerignore @@ -25,8 +25,9 @@ public/bundles/ tests/ var/ vendor/ +node_modules/ .editorconfig -#.env.*.local -#.env.local -#.env.local.php -#.env.test \ No newline at end of file +.env.*.local +.env.local +.env.local.php +.env.test \ No newline at end of file diff --git a/Makefile b/Makefile index 96a5f47..a86a7a7 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,12 @@ COMPOSER = $(PHP_CONT) composer SYMFONY = $(PHP) bin/console PHPUNIT = $(PHP) bin/phpunit + +# Node.js / npm +NODE = $(PHP_CONT) node +NPM = $(PHP_CONT) npm + + # Misc .DEFAULT_GOAL = help .PHONY : help build up start down logs sh composer vendor sf cc @@ -48,6 +54,15 @@ logs: ## Show live logs sh: ## Connect to the PHP FPM container @$(PHP_CONT) sh +node: ## Check Node.js version inside container + @$(NODE) -v + +npm: ## Check npm version inside container + @$(NPM) -v + +npm-install: ## Run npm install inside container + @$(NODE_CONT) npm install + perms: ## Connect to the PHP FPM container @$(PHP_CONT) chown www-data ./var/cache -R @$(PHP_CONT) chmod 0777 ./var/cache -R diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile index 4349cc6..cbfe2d5 100644 --- a/docker/php/Dockerfile +++ b/docker/php/Dockerfile @@ -63,6 +63,12 @@ RUN set -eux; \ chmod +x bin/console; sync; \ fi +# --- Node.js & npm --- +RUN apk add --no-cache nodejs npm +COPY package.json package-lock.json ./ +RUN npm install + + COPY --link docker/php/healthcheck.sh /usr/local/bin/healthcheck RUN chmod +x bin/phpunit; sync; RUN chmod +x healthcheck; sync; @@ -89,4 +95,4 @@ RUN composer dump-env dev; RUN install-php-extensions \ xdebug \ - ; \ No newline at end of file + ; diff --git a/migrations/v1_database_scheme/Different/Version20250627101043_create_storage_table.php b/migrations/v1_database_scheme/Different/Version20250627101043_create_storage_table.php index 953ff82..19c0d3c 100644 --- a/migrations/v1_database_scheme/Different/Version20250627101043_create_storage_table.php +++ b/migrations/v1_database_scheme/Different/Version20250627101043_create_storage_table.php @@ -21,16 +21,16 @@ public function up(Schema $schema): void if (!$sm->tablesExist(['storage'])) { $this->addSql(<<<'SQL' CREATE TABLE storage ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id SERIAL PRIMARY KEY, full_path VARCHAR(255) NOT NULL, type VARCHAR(50) NOT NULL, uid VARCHAR(100) NOT NULL, file_type VARCHAR(20) NOT NULL, - created_at DATETIME NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + created_at TIMESTAMP NOT NULL + ) SQL); } + } public function down(Schema $schema): void diff --git a/migrations/v1_database_scheme/Different/Version20250701024108_update_storage.php b/migrations/v1_database_scheme/Different/Version20250701024108_update_storage.php index 426daed..ad3a25b 100644 --- a/migrations/v1_database_scheme/Different/Version20250701024108_update_storage.php +++ b/migrations/v1_database_scheme/Different/Version20250701024108_update_storage.php @@ -11,7 +11,7 @@ final class Version20250701024108Updatestorage extends AbstractMigration { public function getDescription(): string { - return 'Обновление таблиц storage и tasks: удаление uid, task_type; добавление полей с датами и временем'; + return 'Обновление таблиц storage и tasks: удаление uid, task_type; добавление полей с датами и временем (PostgreSQL совместимость)'; } public function up(Schema $schema): void @@ -19,42 +19,42 @@ public function up(Schema $schema): void $sm = $this->connection->createSchemaManager(); if ($sm->tablesExist(['storage']) && $sm->introspectTable('storage')->hasColumn('uid')) { - $this->addSql('ALTER TABLE storage DROP uid'); + $this->addSql('ALTER TABLE storage DROP COLUMN uid'); } if ($sm->tablesExist(['tasks'])) { $columns = $sm->introspectTable('tasks')->getColumns(); if (isset($columns['task_type'])) { - $this->addSql('ALTER TABLE tasks DROP task_type'); + $this->addSql('ALTER TABLE tasks DROP COLUMN task_type'); } $addColumnsSql = []; if (!isset($columns['date'])) { - $addColumnsSql[] = 'ADD date VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN date TEXT DEFAULT NULL'; } if (!isset($columns['time'])) { - $addColumnsSql[] = 'ADD time VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN time TEXT DEFAULT NULL'; } if (!isset($columns['start_date'])) { - $addColumnsSql[] = 'ADD start_date VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN start_date TEXT DEFAULT NULL'; } if (!isset($columns['start_time'])) { - $addColumnsSql[] = 'ADD start_time VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN start_time TEXT DEFAULT NULL'; } if (!isset($columns['end_date'])) { - $addColumnsSql[] = 'ADD end_date VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN end_date TEXT DEFAULT NULL'; } if (!isset($columns['end_time'])) { - $addColumnsSql[] = 'ADD end_time VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN end_time TEXT DEFAULT NULL'; } if (!isset($columns['repeat'])) { - $addColumnsSql[] = 'ADD `repeat` VARCHAR(255) DEFAULT NULL'; + $addColumnsSql[] = 'ADD COLUMN "repeat" TEXT DEFAULT NULL'; } if (!empty($addColumnsSql)) { - $this->addSql('ALTER TABLE tasks '.implode(', ', $addColumnsSql)); + $this->addSql('ALTER TABLE tasks ' . implode(', ', $addColumnsSql)); } } } @@ -66,19 +66,19 @@ public function down(Schema $schema): void if ($sm->tablesExist(['tasks'])) { $this->addSql(<<<'SQL' ALTER TABLE tasks - ADD task_type VARCHAR(255) NOT NULL, - DROP date, - DROP time, - DROP start_date, - DROP start_time, - DROP end_date, - DROP end_time, - DROP `repeat` + ADD COLUMN task_type VARCHAR(255) NOT NULL, + DROP COLUMN date, + DROP COLUMN time, + DROP COLUMN start_date, + DROP COLUMN start_time, + DROP COLUMN end_date, + DROP COLUMN end_time, + DROP COLUMN "repeat" SQL); } if ($sm->tablesExist(['storage']) && ! $sm->introspectTable('storage')->hasColumn('uid')) { - $this->addSql('ALTER TABLE storage ADD uid VARCHAR(100) NOT NULL'); + $this->addSql('ALTER TABLE storage ADD COLUMN uid VARCHAR(100) NOT NULL'); } } } diff --git a/migrations/v1_database_scheme/Different/Version20250701030209_remove_legacy_notification.php b/migrations/v1_database_scheme/Different/Version20250701030209_remove_legacy_notification.php index 7c8c53b..3243d93 100644 --- a/migrations/v1_database_scheme/Different/Version20250701030209_remove_legacy_notification.php +++ b/migrations/v1_database_scheme/Different/Version20250701030209_remove_legacy_notification.php @@ -44,10 +44,10 @@ public function down(Schema $schema): void $table = $schema->getTable('tasks'); $adds = []; if (!$table->hasColumn('notification_id')) { - $adds[] = 'ADD notification_id INT DEFAULT NULL'; + $adds[] = 'ADD notification_id INTEGER DEFAULT NULL'; } if (!$table->hasColumn('due_date')) { - $adds[] = 'ADD due_date DATETIME DEFAULT NULL'; + $adds[] = 'ADD due_date TIMESTAMP DEFAULT NULL'; } if (!$table->hasColumn('date')) { $adds[] = 'ADD date VARCHAR(255) DEFAULT NULL'; diff --git a/migrations/v1_database_scheme/Different/Version20250706023331_create_languages_tables.php b/migrations/v1_database_scheme/Different/Version20250706023331_create_languages_tables.php index ade295f..cc69758 100644 --- a/migrations/v1_database_scheme/Different/Version20250706023331_create_languages_tables.php +++ b/migrations/v1_database_scheme/Different/Version20250706023331_create_languages_tables.php @@ -14,7 +14,7 @@ final class Version20250706023331Createlanguagestables extends AbstractMigration { public function getDescription(): string { - return 'Creates language and language_page_translation tables for multilingual page support.'; + return 'Creates language and language_page_translation tables for multilingual page support (PostgreSQL).'; } public function up(Schema $schema): void @@ -24,31 +24,26 @@ public function up(Schema $schema): void if (!$sm->tablesExist(['language'])) { $this->addSql(<<<'SQL' CREATE TABLE language ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id SERIAL PRIMARY KEY, prefix VARCHAR(10) NOT NULL, - name VARCHAR(100) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + name VARCHAR(100) NOT NULL + ) SQL); } if (!$sm->tablesExist(['language_page_translation'])) { $this->addSql(<<<'SQL' CREATE TABLE language_page_translation ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - language_id INT NOT NULL, + id SERIAL PRIMARY KEY, + language_id INTEGER NOT NULL, page_name VARCHAR(100) NOT NULL, - page_translate JSON NOT NULL, - INDEX IDX_AFF4D9D182F1BAF4 (language_id), - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + page_translate JSONB NOT NULL, + CONSTRAINT fk_language FOREIGN KEY (language_id) REFERENCES language (id) ON DELETE CASCADE + ) SQL); - $this->addSql(<<<'SQL' - ALTER TABLE language_page_translation - ADD CONSTRAINT FK_AFF4D9D182F1BAF4 - FOREIGN KEY (language_id) REFERENCES language (id) - SQL); + // Индекс для ускорения поиска по language_id + $this->addSql('CREATE INDEX idx_language_translation_language_id ON language_page_translation (language_id)'); } } @@ -57,9 +52,6 @@ public function down(Schema $schema): void $sm = $this->connection->createSchemaManager(); if ($sm->tablesExist(['language_page_translation'])) { - $this->addSql(<<<'SQL' - ALTER TABLE language_page_translation DROP FOREIGN KEY FK_AFF4D9D182F1BAF4 - SQL); $this->addSql('DROP TABLE language_page_translation'); } diff --git a/migrations/v1_database_scheme/Different/Version20250710023600_add_created_at_updated_at_deleted_in_tables.php b/migrations/v1_database_scheme/Different/Version20250710023600_add_created_at_updated_at_deleted_in_tables.php index 1970057..23c68e9 100644 --- a/migrations/v1_database_scheme/Different/Version20250710023600_add_created_at_updated_at_deleted_in_tables.php +++ b/migrations/v1_database_scheme/Different/Version20250710023600_add_created_at_updated_at_deleted_in_tables.php @@ -52,14 +52,14 @@ public function up(Schema $schema): void foreach ($tables as $table) { if ($this->tableExists($schema, $table)) { if (!$this->columnExists($schema, $table, 'created_at')) { - $this->addSql("ALTER TABLE {$table} ADD created_at DATETIME DEFAULT NULL"); + $this->addSql("ALTER TABLE {$table} ADD created_at TIMESTAMP DEFAULT NULL"); } if (!$this->columnExists($schema, $table, 'updated_at')) { - $default = 'storage' === $table ? "DATETIME DEFAULT NULL" : 'DATETIME DEFAULT NULL'; + $default = 'storage' === $table ? "TIMESTAMP DEFAULT NULL" : 'TIMESTAMP DEFAULT NULL'; $this->addSql("ALTER TABLE {$table} ADD updated_at {$default}"); } if (!$this->columnExists($schema, $table, 'is_delete')) { - $this->addSql("ALTER TABLE {$table} ADD is_delete TINYINT(1) NOT NULL"); + $this->addSql("ALTER TABLE {$table} ADD is_delete BOOLEAN NOT NULL"); } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250622074210_create_habits_related_tables.php b/migrations/v1_database_scheme/Habits/Version20250622074210_create_habits_related_tables.php index 7ba0707..f10b67c 100644 --- a/migrations/v1_database_scheme/Habits/Version20250622074210_create_habits_related_tables.php +++ b/migrations/v1_database_scheme/Habits/Version20250622074210_create_habits_related_tables.php @@ -21,106 +21,99 @@ public function up(Schema $schema): void if (!$sm->tablesExist(['date_daily'])) { $this->addSql(<<<'SQL' CREATE TABLE date_daily ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - habit_id INT NOT NULL, - mon TINYINT(1) NOT NULL, - tue TINYINT(1) NOT NULL, - wed TINYINT(1) NOT NULL, - thu TINYINT(1) NOT NULL, - fri TINYINT(1) NOT NULL, - sat TINYINT(1) NOT NULL, - sun TINYINT(1) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + habit_id INTEGER NOT NULL, + mon BOOLEAN NOT NULL, + tue BOOLEAN NOT NULL, + wed BOOLEAN NOT NULL, + thu BOOLEAN NOT NULL, + fri BOOLEAN NOT NULL, + sat BOOLEAN NOT NULL, + sun BOOLEAN NOT NULL + ) SQL); } if (!$sm->tablesExist(['date_repeat_per_month'])) { $this->addSql(<<<'SQL' CREATE TABLE date_repeat_per_month ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - habit_id INT NOT NULL, - day INT NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + habit_id INTEGER NOT NULL, + day INTEGER NOT NULL + ) SQL); } if (!$sm->tablesExist(['date_weekly'])) { $this->addSql(<<<'SQL' CREATE TABLE date_weekly ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - habit_id INT NOT NULL, - count_days INT NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + habit_id INTEGER NOT NULL, + count_days INTEGER NOT NULL + ) SQL); } if (!$sm->tablesExist(['habits'])) { $this->addSql(<<<'SQL' CREATE TABLE habits ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, title VARCHAR(255) NOT NULL, icon_url VARCHAR(255) DEFAULT NULL, quote VARCHAR(255) DEFAULT NULL, date_type VARCHAR(255) NOT NULL, - goal_in_days INT DEFAULT NULL, - begin_date DATETIME DEFAULT NULL, - notification_id INT DEFAULT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + goal_in_days INTEGER DEFAULT NULL, + begin_date TIMESTAMP DEFAULT NULL, + notification_id INTEGER DEFAULT NULL + ) SQL); } if (!$sm->tablesExist(['notifications'])) { $this->addSql(<<<'SQL' CREATE TABLE notifications ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, title VARCHAR(255) NOT NULL, type VARCHAR(255) NOT NULL, payload VARCHAR(255) DEFAULT NULL, - is_active TINYINT(1) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + is_active BOOLEAN NOT NULL + ) SQL); } if (!$sm->tablesExist(['purposes'])) { $this->addSql(<<<'SQL' CREATE TABLE purposes ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, target_type VARCHAR(255) NOT NULL, - target_id INT NOT NULL, - cup_count INT DEFAULT NULL, - millimeter_count INT DEFAULT NULL, - minute_count INT DEFAULT NULL, - hour_count INT DEFAULT NULL, - kilometer_count INT DEFAULT NULL, - pages_count INT DEFAULT NULL, - new_count INT DEFAULT NULL, - check_manually TINYINT(1) DEFAULT NULL, - check_auto TINYINT(1) DEFAULT NULL, - check_close TINYINT(1) DEFAULT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + target_id INTEGER NOT NULL, + cup_count INTEGER DEFAULT NULL, + millimeter_count INTEGER DEFAULT NULL, + minute_count INTEGER DEFAULT NULL, + hour_count INTEGER DEFAULT NULL, + kilometer_count INTEGER DEFAULT NULL, + pages_count INTEGER DEFAULT NULL, + new_count INTEGER DEFAULT NULL, + check_manually BOOLEAN DEFAULT NULL, + check_auto BOOLEAN DEFAULT NULL, + check_close BOOLEAN DEFAULT NULL + ) SQL); } if (!$sm->tablesExist(['tasks'])) { $this->addSql(<<<'SQL' CREATE TABLE tasks ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - habit_id INT NOT NULL, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + habit_id INTEGER NOT NULL, task_type VARCHAR(255) NOT NULL, title_task VARCHAR(255) NOT NULL, - pomodoro_count INT DEFAULT NULL, - pomodoro_id INT DEFAULT NULL, - notification_id INT DEFAULT NULL, - begin_date DATETIME DEFAULT NULL, - due_date DATETIME DEFAULT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + pomodoro_count INTEGER DEFAULT NULL, + pomodoro_id INTEGER DEFAULT NULL, + notification_id INTEGER DEFAULT NULL, + begin_date TIMESTAMP DEFAULT NULL, + due_date TIMESTAMP DEFAULT NULL + ) SQL); } @@ -130,7 +123,7 @@ public function up(Schema $schema): void $this->addSql('ALTER TABLE pomodoro_history ADD target_type VARCHAR(255) NOT NULL'); } if (!isset($columns['target_id'])) { - $this->addSql('ALTER TABLE pomodoro_history ADD target_id INT NOT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ADD target_id INTEGER NOT NULL'); } } } @@ -140,14 +133,14 @@ public function down(Schema $schema): void $sm = $this->connection->createSchemaManager(); foreach ([ - 'date_daily', - 'date_repeat_per_month', - 'date_weekly', - 'habits', - 'notifications', - 'purposes', - 'tasks', - ] as $table) { + 'date_daily', + 'date_repeat_per_month', + 'date_weekly', + 'habits', + 'notifications', + 'purposes', + 'tasks', + ] as $table) { if ($sm->tablesExist([$table])) { $this->addSql("DROP TABLE {$table}"); } @@ -156,11 +149,11 @@ public function down(Schema $schema): void if ($sm->tablesExist(['pomodoro_history'])) { $columns = $sm->listTableColumns('pomodoro_history'); if (isset($columns['target_type'])) { - $this->addSql('ALTER TABLE pomodoro_history DROP target_type'); + $this->addSql('ALTER TABLE pomodoro_history DROP COLUMN target_type'); } if (isset($columns['target_id'])) { - $this->addSql('ALTER TABLE pomodoro_history DROP target_id'); + $this->addSql('ALTER TABLE pomodoro_history DROP COLUMN target_id'); } } } -} +} \ No newline at end of file diff --git a/migrations/v1_database_scheme/Habits/Version20250623032051_updated_habits_tables_structure.php b/migrations/v1_database_scheme/Habits/Version20250623032051_updated_habits_tables_structure.php index 62afbd3..84a61cb 100644 --- a/migrations/v1_database_scheme/Habits/Version20250623032051_updated_habits_tables_structure.php +++ b/migrations/v1_database_scheme/Habits/Version20250623032051_updated_habits_tables_structure.php @@ -21,66 +21,64 @@ public function up(Schema $schema): void if (!$sm->tablesExist('habits_data_juntion')) { $this->addSql(<<<'SQL' CREATE TABLE habits_data_juntion ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - habits_id INT NOT NULL, - data_id INT NOT NULL, - data_type VARCHAR(255) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + habits_id INTEGER NOT NULL, + data_id INTEGER NOT NULL, + data_type VARCHAR(255) NOT NULL + ) SQL); } if (!$sm->tablesExist('habits_pomodor_junction')) { $this->addSql(<<<'SQL' CREATE TABLE habits_pomodor_junction ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - pomodor_id INT NOT NULL, - habits_id INT NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + pomodor_id INTEGER NOT NULL, + habits_id INTEGER NOT NULL + ) SQL); } if ($sm->tablesExist('date_daily') && $sm->introspectTable('date_daily')->hasColumn('habit_id')) { - $this->addSql('ALTER TABLE date_daily DROP habit_id'); + $this->addSql('ALTER TABLE date_daily DROP COLUMN habit_id'); } if ($sm->tablesExist('date_repeat_per_month') && $sm->introspectTable('date_repeat_per_month')->hasColumn('habit_id')) { - $this->addSql('ALTER TABLE date_repeat_per_month DROP habit_id'); + $this->addSql('ALTER TABLE date_repeat_per_month DROP COLUMN habit_id'); } if ($sm->tablesExist('date_weekly') && $sm->introspectTable('date_weekly')->hasColumn('habit_id')) { - $this->addSql('ALTER TABLE date_weekly DROP habit_id'); + $this->addSql('ALTER TABLE date_weekly DROP COLUMN habit_id'); } if ($sm->tablesExist('habits') && $sm->introspectTable('habits')->hasColumn('date_type')) { - $this->addSql('ALTER TABLE habits DROP date_type'); + $this->addSql('ALTER TABLE habits DROP COLUMN date_type'); } if ($sm->tablesExist('pomodoro_history') && $sm->introspectTable('pomodoro_history')->hasColumn('target_type')) { - $this->addSql('ALTER TABLE pomodoro_history DROP target_type, DROP target_id'); + $this->addSql('ALTER TABLE pomodoro_history DROP COLUMN target_type, DROP COLUMN target_id'); } if ($sm->tablesExist('purposes') && $sm->introspectTable('purposes')->hasColumn('target_type')) { - $this->addSql('ALTER TABLE purposes DROP target_type, DROP target_id'); + $this->addSql('ALTER TABLE purposes DROP COLUMN target_type, DROP COLUMN target_id'); } if ($sm->tablesExist('tasks')) { $columns = $sm->introspectTable('tasks')->getColumns(); if (array_key_exists('habit_id', $columns) || array_key_exists('pomodoro_count', $columns) || array_key_exists('pomodoro_id', $columns)) { - $this->addSql('ALTER TABLE tasks ADD purpose_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks ADD COLUMN purpose_id INTEGER DEFAULT NULL'); if (array_key_exists('habit_id', $columns)) { - $this->addSql('ALTER TABLE tasks DROP habit_id'); + $this->addSql('ALTER TABLE tasks DROP COLUMN habit_id'); } if (array_key_exists('pomodoro_count', $columns)) { - $this->addSql('ALTER TABLE tasks DROP pomodoro_count'); + $this->addSql('ALTER TABLE tasks DROP COLUMN pomodoro_count'); } if (array_key_exists('pomodoro_id', $columns)) { - $this->addSql('ALTER TABLE tasks DROP pomodoro_id'); + $this->addSql('ALTER TABLE tasks DROP COLUMN pomodoro_id'); } } } @@ -94,33 +92,34 @@ public function down(Schema $schema): void $this->addSql('DROP TABLE IF EXISTS habits_pomodor_junction'); if ($sm->tablesExist('date_daily')) { - $this->addSql('ALTER TABLE date_daily ADD habit_id INT NOT NULL'); + $this->addSql('ALTER TABLE date_daily ADD COLUMN habit_id INTEGER NOT NULL'); } if ($sm->tablesExist('date_weekly')) { - $this->addSql('ALTER TABLE date_weekly ADD habit_id INT NOT NULL'); + $this->addSql('ALTER TABLE date_weekly ADD COLUMN habit_id INTEGER NOT NULL'); } if ($sm->tablesExist('tasks')) { - $this->addSql('ALTER TABLE tasks ADD habit_id INT NOT NULL'); - $this->addSql('ALTER TABLE tasks ADD pomodoro_id INT DEFAULT NULL'); - $this->addSql('ALTER TABLE tasks CHANGE purpose_id pomodoro_count INT DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks ADD COLUMN habit_id INTEGER NOT NULL'); + $this->addSql('ALTER TABLE tasks ADD COLUMN pomodoro_id INTEGER DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks ADD COLUMN pomodoro_count INTEGER DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks DROP COLUMN purpose_id'); } if ($sm->tablesExist('purposes')) { - $this->addSql('ALTER TABLE purposes ADD target_type VARCHAR(255) NOT NULL, ADD target_id INT NOT NULL'); + $this->addSql('ALTER TABLE purposes ADD COLUMN target_type VARCHAR(255) NOT NULL, ADD COLUMN target_id INTEGER NOT NULL'); } if ($sm->tablesExist('date_repeat_per_month')) { - $this->addSql('ALTER TABLE date_repeat_per_month ADD habit_id INT NOT NULL'); + $this->addSql('ALTER TABLE date_repeat_per_month ADD COLUMN habit_id INTEGER NOT NULL'); } if ($sm->tablesExist('habits')) { - $this->addSql('ALTER TABLE habits ADD date_type VARCHAR(255) NOT NULL'); + $this->addSql('ALTER TABLE habits ADD COLUMN date_type VARCHAR(255) NOT NULL'); } if ($sm->tablesExist('pomodoro_history')) { - $this->addSql('ALTER TABLE pomodoro_history ADD target_type VARCHAR(255) NOT NULL, ADD target_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ADD COLUMN target_type VARCHAR(255) NOT NULL, ADD COLUMN target_id INTEGER DEFAULT NULL'); } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250624025658_add_data_type_column_to_habits.php b/migrations/v1_database_scheme/Habits/Version20250624025658_add_data_type_column_to_habits.php index b80d5d7..604c0e5 100644 --- a/migrations/v1_database_scheme/Habits/Version20250624025658_add_data_type_column_to_habits.php +++ b/migrations/v1_database_scheme/Habits/Version20250624025658_add_data_type_column_to_habits.php @@ -11,7 +11,7 @@ final class Version20250624025658_add_data_type_column_to_habits extends Abstrac { public function getDescription(): string { - return 'Добавляет колонку data_type в таблицу habits, если она отсутствует'; + return 'Добавляет колонку data_type в таблицу habits, если она отсутствует (PostgreSQL версия)'; } public function up(Schema $schema): void @@ -20,7 +20,7 @@ public function up(Schema $schema): void if ($sm->tablesExist(['habits']) && !$sm->introspectTable('habits')->hasColumn('data_type')) { $this->addSql(<<<'SQL' - ALTER TABLE habits ADD data_type VARCHAR(255) NOT NULL + ALTER TABLE habits ADD COLUMN data_type VARCHAR(255) NOT NULL SQL); } } @@ -31,7 +31,7 @@ public function down(Schema $schema): void if ($sm->tablesExist(['habits']) && $sm->introspectTable('habits')->hasColumn('data_type')) { $this->addSql(<<<'SQL' - ALTER TABLE habits DROP data_type + ALTER TABLE habits DROP COLUMN data_type SQL); } } diff --git a/migrations/v1_database_scheme/Habits/Version20250625041914_edit_habits_and_purpose.php b/migrations/v1_database_scheme/Habits/Version20250625041914_edit_habits_and_purpose.php index 2b8e780..4898601 100644 --- a/migrations/v1_database_scheme/Habits/Version20250625041914_edit_habits_and_purpose.php +++ b/migrations/v1_database_scheme/Habits/Version20250625041914_edit_habits_and_purpose.php @@ -11,63 +11,57 @@ final class Version20250625041914Edithabitsandpurpose extends AbstractMigration { public function getDescription(): string { - return 'Изменение таблиц habits и purposes: переименование поля, добавление и удаление колонок'; + return 'Изменение таблиц habits и purposes: переименование поля, добавление и удаление колонок (PostgreSQL)'; } public function up(Schema $schema): void { $sm = $this->connection->createSchemaManager(); + // --- HABITS --- if ($sm->tablesExist(['habits'])) { $columns = $sm->introspectTable('habits')->getColumns(); - $sqlParts = []; - if (!isset($columns['notification_date'])) { - $sqlParts[] = 'ADD notification_date VARCHAR(255) NOT NULL'; + $this->addSql('ALTER TABLE habits ADD COLUMN notification_date VARCHAR(255) NOT NULL'); } if (isset($columns['notification_id'])) { - $sqlParts[] = 'CHANGE notification_id user_id INT DEFAULT NULL'; - } - - if (!empty($sqlParts)) { - $this->addSql('ALTER TABLE habits '.implode(', ', $sqlParts)); + // Переименование notification_id → user_id + $this->addSql('ALTER TABLE habits RENAME COLUMN notification_id TO user_id'); + // Установка DEFAULT NULL + $this->addSql('ALTER TABLE habits ALTER COLUMN user_id DROP NOT NULL'); } } + // --- PURPOSES --- if ($sm->tablesExist(['purposes'])) { $columns = $sm->introspectTable('purposes')->getColumns(); - $addParts = []; - $dropParts = []; if (!isset($columns['habits_id'])) { - $addParts[] = 'ADD habits_id INT NOT NULL'; + $this->addSql('ALTER TABLE purposes ADD COLUMN habits_id INTEGER NOT NULL'); } if (!isset($columns['type'])) { - $addParts[] = 'ADD type VARCHAR(255) NOT NULL'; + $this->addSql('ALTER TABLE purposes ADD COLUMN type VARCHAR(255) NOT NULL'); } if (!isset($columns['count'])) { - $addParts[] = 'ADD count INT NOT NULL'; + $this->addSql('ALTER TABLE purposes ADD COLUMN count INTEGER NOT NULL'); } + foreach (['cup_count', 'millimeter_count', 'minute_count', 'hour_count', 'kilometer_count', 'pages_count', 'new_count'] as $col) { if (isset($columns[$col])) { - $dropParts[] = 'DROP '.$col; + $this->addSql("ALTER TABLE purposes DROP COLUMN $col"); } } - $changeParts = [ - 'CHANGE check_manually check_manually TINYINT(1) NOT NULL', - 'CHANGE check_auto check_auto TINYINT(1) NOT NULL', - 'CHANGE check_close check_close TINYINT(1) NOT NULL', - ]; - $sqlParts = array_merge($addParts, $dropParts, $changeParts); - - if (!empty($sqlParts)) { - $this->addSql('ALTER TABLE purposes '.implode(', ', $sqlParts)); + foreach (['check_manually', 'check_auto', 'check_close'] as $col) { + if (isset($columns[$col])) { + $this->addSql("ALTER TABLE purposes ALTER COLUMN $col SET NOT NULL"); + $this->addSql("ALTER TABLE purposes ALTER COLUMN $col TYPE BOOLEAN USING $col::BOOLEAN"); + } } } } @@ -76,42 +70,42 @@ public function down(Schema $schema): void { $sm = $this->connection->createSchemaManager(); + // --- HABITS --- if ($sm->tablesExist(['habits'])) { - $this->addSql(<<<'SQL' - ALTER TABLE habits - DROP notification_date, - CHANGE user_id notification_id INT DEFAULT NULL - SQL); + $columns = $sm->introspectTable('habits')->getColumns(); + + if (isset($columns['notification_date'])) { + $this->addSql('ALTER TABLE habits DROP COLUMN notification_date'); + } + if (isset($columns['user_id'])) { + $this->addSql('ALTER TABLE habits RENAME COLUMN user_id TO notification_id'); + $this->addSql('ALTER TABLE habits ALTER COLUMN notification_id SET DEFAULT NULL'); + } } + // --- PURPOSES --- if ($sm->tablesExist(['purposes'])) { $columns = $sm->introspectTable('purposes')->getColumns(); - $addParts = []; - $dropParts = []; foreach (['cup_count', 'millimeter_count', 'minute_count', 'hour_count', 'kilometer_count', 'pages_count', 'new_count'] as $col) { if (!isset($columns[$col])) { - $addParts[] = 'ADD '.$col.' INT DEFAULT NULL'; + $this->addSql("ALTER TABLE purposes ADD COLUMN $col INTEGER DEFAULT NULL"); } } + foreach (['habits_id', 'type', 'count'] as $col) { if (isset($columns[$col])) { - $dropParts[] = 'DROP '.$col; + $this->addSql("ALTER TABLE purposes DROP COLUMN $col"); } } - $changeParts = [ - 'CHANGE check_manually check_manually TINYINT(1) DEFAULT NULL', - 'CHANGE check_auto check_auto TINYINT(1) DEFAULT NULL', - 'CHANGE check_close check_close TINYINT(1) DEFAULT NULL', - ]; - $sqlParts = array_merge($addParts, $dropParts, $changeParts); - - if (!empty($sqlParts)) { - $this->addSql('ALTER TABLE purposes '.implode(', ', $sqlParts)); + foreach (['check_manually', 'check_auto', 'check_close'] as $col) { + if (isset($columns[$col])) { + $this->addSql("ALTER TABLE purposes ALTER COLUMN $col DROP NOT NULL"); + } } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250626121151_added_manually_count_in_purpose.php b/migrations/v1_database_scheme/Habits/Version20250626121151_added_manually_count_in_purpose.php index aedcf83..852905b 100644 --- a/migrations/v1_database_scheme/Habits/Version20250626121151_added_manually_count_in_purpose.php +++ b/migrations/v1_database_scheme/Habits/Version20250626121151_added_manually_count_in_purpose.php @@ -11,7 +11,7 @@ final class Version20250626121151Addedmanuallycountinpurpose extends AbstractMig { public function getDescription(): string { - return 'Добавление поля manually_count в таблицу purposes (с проверкой на существование таблицы)'; + return 'Добавление поля manually_count в таблицу purposes (с проверкой на существование таблицы, PostgreSQL версия)'; } public function up(Schema $schema): void @@ -19,9 +19,13 @@ public function up(Schema $schema): void $sm = $this->connection->createSchemaManager(); if ($sm->tablesExist(['purposes'])) { - $this->addSql(<<<'SQL' - ALTER TABLE purposes ADD manually_count INT NOT NULL - SQL); + $columns = $sm->introspectTable('purposes')->getColumns(); + + if (!isset($columns['manually_count'])) { + $this->addSql(<<<'SQL' + ALTER TABLE purposes ADD COLUMN manually_count INTEGER NOT NULL + SQL); + } } } @@ -30,9 +34,13 @@ public function down(Schema $schema): void $sm = $this->connection->createSchemaManager(); if ($sm->tablesExist(['purposes'])) { - $this->addSql(<<<'SQL' - ALTER TABLE purposes DROP manually_count - SQL); + $columns = $sm->introspectTable('purposes')->getColumns(); + + if (isset($columns['manually_count'])) { + $this->addSql(<<<'SQL' + ALTER TABLE purposes DROP COLUMN manually_count + SQL); + } } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250626131625_rename_manually_count_in_purpose.php b/migrations/v1_database_scheme/Habits/Version20250626131625_rename_manually_count_in_purpose.php index 7e0aa8f..c9bb588 100644 --- a/migrations/v1_database_scheme/Habits/Version20250626131625_rename_manually_count_in_purpose.php +++ b/migrations/v1_database_scheme/Habits/Version20250626131625_rename_manually_count_in_purpose.php @@ -11,7 +11,7 @@ final class Version20250626131625Renamemanuallycountinpurpose extends AbstractMi { public function getDescription(): string { - return 'Переименование поля manually_count в auto_count в таблице purposes (с проверкой на существование)'; + return 'Переименование поля manually_count в auto_count в таблице purposes (PostgreSQL)'; } public function up(Schema $schema): void @@ -22,7 +22,9 @@ public function up(Schema $schema): void $columns = $sm->introspectTable('purposes')->getColumns(); if (isset($columns['manually_count']) && !isset($columns['auto_count'])) { - $this->addSql('ALTER TABLE purposes CHANGE manually_count auto_count INT NOT NULL'); + $this->addSql('ALTER TABLE purposes RENAME COLUMN manually_count TO auto_count'); + $this->addSql('ALTER TABLE purposes ALTER COLUMN auto_count TYPE INTEGER USING auto_count::integer'); + $this->addSql('ALTER TABLE purposes ALTER COLUMN auto_count SET NOT NULL'); } } } @@ -35,7 +37,9 @@ public function down(Schema $schema): void $columns = $sm->introspectTable('purposes')->getColumns(); if (isset($columns['auto_count']) && !isset($columns['manually_count'])) { - $this->addSql('ALTER TABLE purposes CHANGE auto_count manually_count INT NOT NULL'); + $this->addSql('ALTER TABLE purposes RENAME COLUMN auto_count TO manually_count'); + $this->addSql('ALTER TABLE purposes ALTER COLUMN manually_count TYPE INTEGER USING manually_count::integer'); + $this->addSql('ALTER TABLE purposes ALTER COLUMN manually_count SET NOT NULL'); } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250626134651_create_habits_history.php b/migrations/v1_database_scheme/Habits/Version20250626134651_create_habits_history.php index dcb298e..e6d467b 100644 --- a/migrations/v1_database_scheme/Habits/Version20250626134651_create_habits_history.php +++ b/migrations/v1_database_scheme/Habits/Version20250626134651_create_habits_history.php @@ -11,7 +11,7 @@ final class Version20250626134651Createhabitshistory extends AbstractMigration { public function getDescription(): string { - return 'Создание таблицы habits_history с проверкой на существование'; + return 'Создание таблицы habits_history с проверкой на существование (PostgreSQL)'; } public function up(Schema $schema): void @@ -21,16 +21,15 @@ public function up(Schema $schema): void if (!$sm->tablesExist(['habits_history'])) { $this->addSql(<<<'SQL' CREATE TABLE habits_history ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - count INT NOT NULL, - habits_id INT NOT NULL, - count_end INT NOT NULL, - is_done TINYINT(1) NOT NULL, - created_at DATETIME NOT NULL, - updated_at DATETIME DEFAULT NULL, - is_deleted TINYINT(1) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + count INTEGER NOT NULL, + habits_id INTEGER NOT NULL, + count_end INTEGER NOT NULL, + is_done BOOLEAN NOT NULL, + created_at TIMESTAMP NOT NULL, + updated_at TIMESTAMP DEFAULT NULL, + is_deleted BOOLEAN NOT NULL + ) SQL); } } diff --git a/migrations/v1_database_scheme/Habits/Version20250626135514_added_user_id_in_habits_history.php b/migrations/v1_database_scheme/Habits/Version20250626135514_added_user_id_in_habits_history.php index ecd425d..c004ff2 100644 --- a/migrations/v1_database_scheme/Habits/Version20250626135514_added_user_id_in_habits_history.php +++ b/migrations/v1_database_scheme/Habits/Version20250626135514_added_user_id_in_habits_history.php @@ -11,7 +11,7 @@ final class Version20250626135514Addeduseridinhabitshistory extends AbstractMigr { public function getDescription(): string { - return 'Добавление поля user_id в таблицу habits_history (с проверкой на существование таблицы)'; + return 'Добавление поля user_id в таблицу habits_history (с проверкой на существование таблицы, PostgreSQL версия)'; } public function up(Schema $schema): void @@ -22,7 +22,9 @@ public function up(Schema $schema): void $columns = $sm->introspectTable('habits_history')->getColumns(); if (!isset($columns['user_id'])) { - $this->addSql('ALTER TABLE habits_history ADD user_id INT NOT NULL'); + $this->addSql(<<<'SQL' + ALTER TABLE habits_history ADD COLUMN user_id INTEGER NOT NULL + SQL); } } } @@ -35,7 +37,9 @@ public function down(Schema $schema): void $columns = $sm->introspectTable('habits_history')->getColumns(); if (isset($columns['user_id'])) { - $this->addSql('ALTER TABLE habits_history DROP user_id'); + $this->addSql(<<<'SQL' + ALTER TABLE habits_history DROP COLUMN user_id + SQL); } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250627034608_added_recorded_at_in_habits_history.php b/migrations/v1_database_scheme/Habits/Version20250627034608_added_recorded_at_in_habits_history.php index 7d842ae..0ccf661 100644 --- a/migrations/v1_database_scheme/Habits/Version20250627034608_added_recorded_at_in_habits_history.php +++ b/migrations/v1_database_scheme/Habits/Version20250627034608_added_recorded_at_in_habits_history.php @@ -11,7 +11,7 @@ final class Version20250627034608Addedrecordedatinhabitshistory extends Abstract { public function getDescription(): string { - return 'Добавление поля recorded_at в таблицу habits_history с защитой от падения при отсутствии таблицы'; + return 'Добавление поля recorded_at в таблицу habits_history с защитой от падения при отсутствии таблицы (PostgreSQL версия)'; } public function up(Schema $schema): void @@ -22,7 +22,7 @@ public function up(Schema $schema): void $columns = $sm->introspectTable('habits_history')->getColumns(); if (!isset($columns['recorded_at'])) { - $this->addSql('ALTER TABLE habits_history ADD recorded_at DATETIME NOT NULL'); + $this->addSql('ALTER TABLE habits_history ADD COLUMN recorded_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL'); } } } @@ -35,7 +35,7 @@ public function down(Schema $schema): void $columns = $sm->introspectTable('habits_history')->getColumns(); if (isset($columns['recorded_at'])) { - $this->addSql('ALTER TABLE habits_history DROP recorded_at'); + $this->addSql('ALTER TABLE habits_history DROP COLUMN recorded_at'); } } } diff --git a/migrations/v1_database_scheme/Habits/Version20250627040414_added_indexes_habits_history.php b/migrations/v1_database_scheme/Habits/Version20250627040414_added_indexes_habits_history.php index 4f0f8f2..0070bc4 100644 --- a/migrations/v1_database_scheme/Habits/Version20250627040414_added_indexes_habits_history.php +++ b/migrations/v1_database_scheme/Habits/Version20250627040414_added_indexes_habits_history.php @@ -11,7 +11,7 @@ final class Version20250627040414Addedindexeshabitshistory extends AbstractMigra { public function getDescription(): string { - return 'Создание индексов по полям user_id, recorded_at в таблице habits_history с безопасной проверкой'; + return 'Создание индексов по полям user_id, recorded_at в таблице habits_history (PostgreSQL)'; } public function up(Schema $schema): void @@ -22,7 +22,7 @@ public function up(Schema $schema): void $table = $sm->introspectTable('habits_history'); $indexes = $table->getIndexes(); - $indexNames = array_map(fn ($index) => $index->getName(), $indexes); + $indexNames = array_map(fn ($index) => strtolower($index->getName()), $indexes); if (!in_array('idx_user', $indexNames, true)) { $this->addSql('CREATE INDEX idx_user ON habits_history (user_id)'); @@ -40,24 +40,10 @@ public function up(Schema $schema): void public function down(Schema $schema): void { - $sm = $this->connection->createSchemaManager(); - - if ($sm->tablesExist(['habits_history'])) { - $table = $sm->introspectTable('habits_history'); - $indexes = $table->getIndexes(); - $indexNames = array_map(fn ($index) => $index->getName(), $indexes); - - if (in_array('idx_user', $indexNames, true)) { - $this->addSql('DROP INDEX idx_user ON habits_history'); - } - - if (in_array('idx_recorded_at', $indexNames, true)) { - $this->addSql('DROP INDEX idx_recorded_at ON habits_history'); - } - - if (in_array('idx_user_date', $indexNames, true)) { - $this->addSql('DROP INDEX idx_user_date ON habits_history'); - } + if ($this->connection->createSchemaManager()->tablesExist(['habits_history'])) { + $this->addSql('DROP INDEX IF EXISTS idx_user'); + $this->addSql('DROP INDEX IF EXISTS idx_recorded_at'); + $this->addSql('DROP INDEX IF EXISTS idx_user_date'); } } } diff --git a/migrations/v1_database_scheme/Pomodoro/Version20250622052239_created_table_pomodoro_history.php b/migrations/v1_database_scheme/Pomodoro/Version20250622052239_created_table_pomodoro_history.php index af5ddd1..891ff56 100644 --- a/migrations/v1_database_scheme/Pomodoro/Version20250622052239_created_table_pomodoro_history.php +++ b/migrations/v1_database_scheme/Pomodoro/Version20250622052239_created_table_pomodoro_history.php @@ -11,7 +11,7 @@ final class Version20250622052239_created_table_pomodoro_history extends Abstrac { public function getDescription(): string { - return 'Создание таблицы pomodoro_history с проверкой существования'; + return 'Создание таблицы pomodoro_history (PostgreSQL совместимость)'; } public function up(Schema $schema): void @@ -21,17 +21,16 @@ public function up(Schema $schema): void if (!$schemaManager->tablesExist(['pomodoro_history'])) { $this->addSql(<<<'SQL' CREATE TABLE pomodoro_history ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - user_id INT NOT NULL, - time_focus INT NOT NULL, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_id INTEGER NOT NULL, + time_focus INTEGER NOT NULL, period_label VARCHAR(10) NOT NULL, - focus_start DATETIME NOT NULL, - focus_end DATETIME NOT NULL, - create_date DATETIME NOT NULL, - update_date DATETIME DEFAULT NULL, - is_delete INT NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + focus_start TIMESTAMP NOT NULL, + focus_end TIMESTAMP NOT NULL, + create_date TIMESTAMP NOT NULL, + update_date TIMESTAMP DEFAULT NULL, + is_delete BOOLEAN NOT NULL DEFAULT FALSE + ) SQL); } } diff --git a/migrations/v1_database_scheme/Pomodoro/Version20250623021008_added_pomodoro_history_default_null.php b/migrations/v1_database_scheme/Pomodoro/Version20250623021008_added_pomodoro_history_default_null.php index 33e9fa6..ace513f 100644 --- a/migrations/v1_database_scheme/Pomodoro/Version20250623021008_added_pomodoro_history_default_null.php +++ b/migrations/v1_database_scheme/Pomodoro/Version20250623021008_added_pomodoro_history_default_null.php @@ -11,7 +11,7 @@ final class Version20250623021008_added_pomodoro_history_default_null extends Ab { public function getDescription(): string { - return 'Изменение target_id в pomodoro_history на DEFAULT NULL'; + return 'Изменение target_id в pomodoro_history: сделать DEFAULT NULL (PostgreSQL)'; } public function up(Schema $schema): void @@ -22,7 +22,8 @@ public function up(Schema $schema): void $columns = $sm->introspectTable('pomodoro_history')->getColumns(); if (isset($columns['target_id'])) { - $this->addSql('ALTER TABLE pomodoro_history CHANGE target_id target_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ALTER COLUMN target_id DROP NOT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ALTER COLUMN target_id SET DEFAULT NULL'); } } } @@ -35,7 +36,8 @@ public function down(Schema $schema): void $columns = $sm->introspectTable('pomodoro_history')->getColumns(); if (isset($columns['target_id'])) { - $this->addSql('ALTER TABLE pomodoro_history CHANGE target_id target_id INT NOT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ALTER COLUMN target_id SET NOT NULL'); + $this->addSql('ALTER TABLE pomodoro_history ALTER COLUMN target_id DROP DEFAULT'); } } } diff --git a/migrations/v1_database_scheme/Pomodoro/Version20250811112548_added_title.php b/migrations/v1_database_scheme/Pomodoro/Version20250811112548_added_title.php index 7ae62b3..18ea672 100644 --- a/migrations/v1_database_scheme/Pomodoro/Version20250811112548_added_title.php +++ b/migrations/v1_database_scheme/Pomodoro/Version20250811112548_added_title.php @@ -11,26 +11,32 @@ final class Version20250811112548AddedTitle extends AbstractMigration { public function getDescription(): string { - return 'Добавляет колонку title в таблицу pomodoro_history, если её нет'; + return 'Добавляет колонку title в таблицу pomodoro_history, если её нет (PostgreSQL совместимость)'; } public function up(Schema $schema): void { $sm = $this->connection->createSchemaManager(); - $columns = $sm->listTableColumns('pomodoro_history'); - if (!array_key_exists('title', $columns)) { - $this->addSql('ALTER TABLE pomodoro_history ADD title VARCHAR(120) NOT NULL'); + if ($sm->tablesExist(['pomodoro_history'])) { + $columns = $sm->introspectTable('pomodoro_history')->getColumns(); + + if (!isset($columns['title'])) { + $this->addSql('ALTER TABLE pomodoro_history ADD COLUMN title VARCHAR(120) NOT NULL'); + } } } public function down(Schema $schema): void { $sm = $this->connection->createSchemaManager(); - $columns = $sm->listTableColumns('pomodoro_history'); - if (array_key_exists('title', $columns)) { - $this->addSql('ALTER TABLE pomodoro_history DROP title'); + if ($sm->tablesExist(['pomodoro_history'])) { + $columns = $sm->introspectTable('pomodoro_history')->getColumns(); + + if (isset($columns['title'])) { + $this->addSql('ALTER TABLE pomodoro_history DROP COLUMN title'); + } } } } diff --git a/migrations/v1_database_scheme/Tasks/Version20250701030734_added_user_id_in_tasks.php b/migrations/v1_database_scheme/Tasks/Version20250701030734_added_user_id_in_tasks.php index 446e71f..44d433f 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250701030734_added_user_id_in_tasks.php +++ b/migrations/v1_database_scheme/Tasks/Version20250701030734_added_user_id_in_tasks.php @@ -14,7 +14,7 @@ final class Version20250701030734Addeduseridintasks extends AbstractMigration { public function getDescription(): string { - return 'Adds user_id column to tasks table if it exists'; + return 'Adds user_id column to tasks table if it exists (PostgreSQL adaptation)'; } public function up(Schema $schema): void @@ -25,7 +25,7 @@ public function up(Schema $schema): void $columns = $sm->introspectTable('tasks')->getColumns(); if (!isset($columns['user_id'])) { - $this->addSql('ALTER TABLE tasks ADD user_id INT NOT NULL'); + $this->addSql('ALTER TABLE tasks ADD COLUMN user_id INTEGER NOT NULL'); } } } @@ -38,7 +38,7 @@ public function down(Schema $schema): void $columns = $sm->introspectTable('tasks')->getColumns(); if (isset($columns['user_id'])) { - $this->addSql('ALTER TABLE tasks DROP user_id'); + $this->addSql('ALTER TABLE tasks DROP COLUMN user_id'); } } } diff --git a/migrations/v1_database_scheme/Tasks/Version20250701033926_rename_repeat_to_repeat_mode_in_tasks.php b/migrations/v1_database_scheme/Tasks/Version20250701033926_rename_repeat_to_repeat_mode_in_tasks.php index e0bf0a5..118d613 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250701033926_rename_repeat_to_repeat_mode_in_tasks.php +++ b/migrations/v1_database_scheme/Tasks/Version20250701033926_rename_repeat_to_repeat_mode_in_tasks.php @@ -14,7 +14,7 @@ final class Version20250701033926Renamerepeattorepeatmodeintasks extends Abstrac { public function getDescription(): string { - return 'Renames "repeat" column to "repeat_mode" in the tasks table, if it exists.'; + return 'Renames "repeat" column to "repeat_mode" in the tasks table, if it exists (PostgreSQL adaptation).'; } public function up(Schema $schema): void @@ -25,7 +25,7 @@ public function up(Schema $schema): void $columns = $table->getColumns(); if (isset($columns['repeat']) && !isset($columns['repeat_mode'])) { - $this->addSql('ALTER TABLE tasks CHANGE `repeat` repeat_mode VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks RENAME COLUMN "repeat" TO repeat_mode'); } } } @@ -38,7 +38,7 @@ public function down(Schema $schema): void $columns = $table->getColumns(); if (isset($columns['repeat_mode']) && !isset($columns['repeat'])) { - $this->addSql('ALTER TABLE tasks CHANGE repeat_mode `repeat` VARCHAR(255) DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks RENAME COLUMN repeat_mode TO "repeat"'); } } } diff --git a/migrations/v1_database_scheme/Tasks/Version20250701035053_added_description_in_tasks.php b/migrations/v1_database_scheme/Tasks/Version20250701035053_added_description_in_tasks.php index ce86cf8..8f8a8b8 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250701035053_added_description_in_tasks.php +++ b/migrations/v1_database_scheme/Tasks/Version20250701035053_added_description_in_tasks.php @@ -14,7 +14,7 @@ final class Version20250701035053Addeddescriptionintasks extends AbstractMigrati { public function getDescription(): string { - return 'Adds "description" column to the "tasks" table, if it exists.'; + return 'Adds "description" column to the "tasks" table, if it exists (PostgreSQL adaptation).'; } public function up(Schema $schema): void @@ -25,7 +25,7 @@ public function up(Schema $schema): void $columns = $table->getColumns(); if (!isset($columns['description'])) { - $this->addSql('ALTER TABLE tasks ADD description LONGTEXT DEFAULT NULL'); + $this->addSql('ALTER TABLE tasks ADD description TEXT'); } } } @@ -38,7 +38,7 @@ public function down(Schema $schema): void $columns = $table->getColumns(); if (isset($columns['description'])) { - $this->addSql('ALTER TABLE tasks DROP description'); + $this->addSql('ALTER TABLE tasks DROP COLUMN description'); } } } diff --git a/migrations/v1_database_scheme/Tasks/Version20250708021744_create_matric_column.php b/migrations/v1_database_scheme/Tasks/Version20250708021744_create_matric_column.php index 9da0d66..5d19cd8 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250708021744_create_matric_column.php +++ b/migrations/v1_database_scheme/Tasks/Version20250708021744_create_matric_column.php @@ -19,39 +19,41 @@ public function getDescription(): string public function up(Schema $schema): void { - if (!$schema->hasTable('matric_column')) { + $sm = $this->connection->createSchemaManager(); + + if (!$sm->tablesExist(['matric_column'])) { $this->addSql(<<<'SQL' CREATE TABLE matric_column ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, first_column_name VARCHAR(255) NOT NULL, second_column_name VARCHAR(255) NOT NULL, third_column_name VARCHAR(255) NOT NULL, - fourth_column_name VARCHAR(255) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + fourth_column_name VARCHAR(255) NOT NULL + ) SQL); } - if (!$schema->hasTable('matric_junction')) { + if (!$sm->tablesExist(['matric_junction'])) { $this->addSql(<<<'SQL' CREATE TABLE matric_junction ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - column_number INT NOT NULL, - task_number INT NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + column_number INTEGER NOT NULL, + task_number INTEGER NOT NULL + ) SQL); } } public function down(Schema $schema): void { - if ($schema->hasTable('matric_junction')) { + $sm = $this->connection->createSchemaManager(); + + if ($sm->tablesExist(['matric_junction'])) { $this->addSql('DROP TABLE matric_junction'); } - if ($schema->hasTable('matric_column')) { + if ($sm->tablesExist(['matric_column'])) { $this->addSql('DROP TABLE matric_column'); } } -} +} \ No newline at end of file diff --git a/migrations/v1_database_scheme/Tasks/Version20250708030931_edit_matric_column.php b/migrations/v1_database_scheme/Tasks/Version20250708030931_edit_matric_column.php index 7b59071..b4fdd99 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250708030931_edit_matric_column.php +++ b/migrations/v1_database_scheme/Tasks/Version20250708030931_edit_matric_column.php @@ -14,20 +14,34 @@ final class Version20250708030931Editmatriccolumn extends AbstractMigration { public function getDescription(): string { - return 'Add user_id column to matric_column table'; + return 'Add user_id column to matric_column table (PostgreSQL adaptation)'; } public function up(Schema $schema): void { - if ($schema->hasTable('matric_column') && !$schema->getTable('matric_column')->hasColumn('user_id')) { - $this->addSql('ALTER TABLE matric_column ADD user_id INT NOT NULL'); + $sm = $this->connection->createSchemaManager(); + + if ($sm->tablesExist(['matric_column'])) { + $table = $sm->introspectTable('matric_column'); + $columns = $table->getColumns(); + + if (!isset($columns['user_id'])) { + $this->addSql('ALTER TABLE matric_column ADD user_id INTEGER NOT NULL'); + } } } public function down(Schema $schema): void { - if ($schema->hasTable('matric_column') && $schema->getTable('matric_column')->hasColumn('user_id')) { - $this->addSql('ALTER TABLE matric_column DROP user_id'); + $sm = $this->connection->createSchemaManager(); + + if ($sm->tablesExist(['matric_column'])) { + $table = $sm->introspectTable('matric_column'); + $columns = $table->getColumns(); + + if (isset($columns['user_id'])) { + $this->addSql('ALTER TABLE matric_column DROP COLUMN user_id'); + } } } } diff --git a/migrations/v1_database_scheme/Tasks/Version20250802083849_create_tasks_history_table.php b/migrations/v1_database_scheme/Tasks/Version20250802083849_create_tasks_history_table.php index 64bd99b..61ad8b0 100644 --- a/migrations/v1_database_scheme/Tasks/Version20250802083849_create_tasks_history_table.php +++ b/migrations/v1_database_scheme/Tasks/Version20250802083849_create_tasks_history_table.php @@ -11,7 +11,7 @@ final class Version20250802083849_create_tasks_history_table extends AbstractMig { public function getDescription(): string { - return ''; + return 'Создание таблицы tasks_history для PostgreSQL'; } public function up(Schema $schema): void @@ -20,17 +20,18 @@ public function up(Schema $schema): void if (!$sm->tablesExist(['tasks_history'])) { $this->addSql('CREATE TABLE tasks_history ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - tasks_id INT NOT NULL, - user_id INT NOT NULL, - time_close DATETIME DEFAULT NULL, - time_close_month VARCHAR(255) DEFAULT NULL, - created_at DATETIME DEFAULT NULL, - updated_at DATETIME DEFAULT NULL, - is_delete TINYINT(1) NOT NULL, - PRIMARY KEY(id), - INDEX IDX_USER_ID (user_id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + id SERIAL PRIMARY KEY, + tasks_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + time_close TIMESTAMP NULL, + time_close_month VARCHAR(255) NULL, + created_at TIMESTAMP NULL, + updated_at TIMESTAMP NULL, + is_delete BOOLEAN NOT NULL + )'); + + + $this->addSql('CREATE INDEX IDX_USER_ID ON tasks_history(user_id)'); } } diff --git a/migrations/v1_database_scheme/Users/Version20250617181327_create_users_table.php b/migrations/v1_database_scheme/Users/Version20250617181327_create_users_table.php index 7eaffbf..037cce5 100644 --- a/migrations/v1_database_scheme/Users/Version20250617181327_create_users_table.php +++ b/migrations/v1_database_scheme/Users/Version20250617181327_create_users_table.php @@ -16,44 +16,51 @@ public function getDescription(): string public function up(Schema $schema): void { - $schemaManager = $this->connection->createSchemaManager(); + $sm = $this->connection->createSchemaManager(); - if (!$schemaManager->tablesExist(['Users'])) { + if (!$sm->tablesExist(['Users'])) { $this->addSql(<<<'SQL' CREATE TABLE Users ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, - premium INT NOT NULL, - role VARCHAR(35) NOT NULL, - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + premium INTEGER NOT NULL, + role VARCHAR(35) NOT NULL + ) SQL); } - if (!$schemaManager->tablesExist(['messenger_messages'])) { + if (!$sm->tablesExist(['messenger_messages'])) { $this->addSql(<<<'SQL' CREATE TABLE messenger_messages ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - body LONGTEXT NOT NULL, - headers LONGTEXT NOT NULL, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + body TEXT NOT NULL, + headers TEXT NOT NULL, queue_name VARCHAR(190) NOT NULL, - created_at DATETIME NOT NULL, - available_at DATETIME NOT NULL, - delivered_at DATETIME DEFAULT NULL, - INDEX IDX_75EA56E0FB7336F0 (queue_name), - INDEX IDX_75EA56E0E3BD61CE (available_at), - INDEX IDX_75EA56E016BA31DB (delivered_at), - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + created_at TIMESTAMP NOT NULL, + available_at TIMESTAMP NOT NULL, + delivered_at TIMESTAMP + ) SQL); + + + $this->addSql('CREATE INDEX IDX_QUEUE_NAME ON messenger_messages(queue_name)'); + $this->addSql('CREATE INDEX IDX_AVAILABLE_AT ON messenger_messages(available_at)'); + $this->addSql('CREATE INDEX IDX_DELIVERED_AT ON messenger_messages(delivered_at)'); } } public function down(Schema $schema): void { - $this->addSql('DROP TABLE IF EXISTS Users'); - $this->addSql('DROP TABLE IF EXISTS messenger_messages'); + $sm = $this->connection->createSchemaManager(); + + if ($sm->tablesExist(['messenger_messages'])) { + $this->addSql('DROP TABLE messenger_messages'); + } + + if ($sm->tablesExist(['Users'])) { + $this->addSql('DROP TABLE Users'); + } } } diff --git a/migrations/v1_database_scheme/Users/Version20250619012538_added_users_users_setting_and_created_refresh_tokens_table.php b/migrations/v1_database_scheme/Users/Version20250619012538_added_users_users_setting_and_created_refresh_tokens_table.php index 2572918..7e703ec 100644 --- a/migrations/v1_database_scheme/Users/Version20250619012538_added_users_users_setting_and_created_refresh_tokens_table.php +++ b/migrations/v1_database_scheme/Users/Version20250619012538_added_users_users_setting_and_created_refresh_tokens_table.php @@ -16,41 +16,37 @@ public function getDescription(): string public function up(Schema $schema): void { - $schemaManager = $this->connection->createSchemaManager(); - - if (!$schemaManager->tablesExist(['refresh_tokens'])) { + $sm = $this->connection->createSchemaManager(); + if (!$sm->tablesExist(['refresh_tokens'])) { $this->addSql(<<<'SQL' CREATE TABLE refresh_tokens ( - id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, refresh_token VARCHAR(128) NOT NULL, username VARCHAR(255) NOT NULL, - valid DATETIME NOT NULL, - UNIQUE INDEX UNIQ_9BACE7E1C74F2195 (refresh_token), - PRIMARY KEY(id) - ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB + valid TIMESTAMP NOT NULL, + UNIQUE (refresh_token) + ) SQL); } - if ($schemaManager->tablesExist(['Users'])) { - $columns = $schemaManager->listTableColumns('Users'); + if ($sm->tablesExist(['Users'])) { + $columns = $sm->listTableColumns('Users'); if (!array_key_exists('users_settings', $columns)) { - $this->addSql(<<<'SQL' - ALTER TABLE Users ADD users_settings JSON DEFAULT NULL - SQL); + $this->addSql('ALTER TABLE Users ADD users_settings JSON DEFAULT NULL'); } } } public function down(Schema $schema): void { - $schemaManager = $this->connection->createSchemaManager(); + $sm = $this->connection->createSchemaManager(); - if ($schemaManager->tablesExist(['refresh_tokens'])) { + if ($sm->tablesExist(['refresh_tokens'])) { $this->addSql('DROP TABLE refresh_tokens'); } - if ($schemaManager->tablesExist(['Users'])) { - $columns = $schemaManager->listTableColumns('Users'); + if ($sm->tablesExist(['Users'])) { + $columns = $sm->listTableColumns('Users'); if (array_key_exists('users_settings', $columns)) { $this->addSql('ALTER TABLE Users DROP COLUMN users_settings'); } diff --git a/migrations/v1_database_scheme/Users/Version20250619013720_added_index_in_users.php b/migrations/v1_database_scheme/Users/Version20250619013720_added_index_in_users.php index af2a439..2539be8 100644 --- a/migrations/v1_database_scheme/Users/Version20250619013720_added_index_in_users.php +++ b/migrations/v1_database_scheme/Users/Version20250619013720_added_index_in_users.php @@ -11,23 +11,23 @@ final class Version20250619013720_added_index_in_users extends AbstractMigration { public function getDescription(): string { - return 'Добавление уникальных индексов на поля name и email в таблице Users, с проверкой наличия перед созданием'; + return 'Добавление уникальных индексов на поля name и email в таблице users (PostgreSQL адаптация)'; } public function up(Schema $schema): void { $schemaManager = $this->connection->createSchemaManager(); - if ($schemaManager->tablesExist(['Users'])) { - $indexes = $schemaManager->listTableIndexes('Users'); + if ($schemaManager->tablesExist(['users'])) { + $indexes = $schemaManager->listTableIndexes('users'); $existingIndexNames = array_map(fn ($index) => strtolower($index->getName()), $indexes); if (!in_array('uniq_1483a5e95e237e06', $existingIndexNames, true)) { - $this->addSql('CREATE UNIQUE INDEX UNIQ_1483A5E95E237E06 ON Users (name)'); + $this->addSql('CREATE UNIQUE INDEX uniq_1483a5e95e237e06 ON users (name)'); } if (!in_array('uniq_1483a5e9e7927c74', $existingIndexNames, true)) { - $this->addSql('CREATE UNIQUE INDEX UNIQ_1483A5E9E7927C74 ON Users (email)'); + $this->addSql('CREATE UNIQUE INDEX uniq_1483a5e9e7927c74 ON users (email)'); } } } @@ -36,16 +36,16 @@ public function down(Schema $schema): void { $schemaManager = $this->connection->createSchemaManager(); - if ($schemaManager->tablesExist(['Users'])) { - $indexes = $schemaManager->listTableIndexes('Users'); + if ($schemaManager->tablesExist(['users'])) { + $indexes = $schemaManager->listTableIndexes('users'); $existingIndexNames = array_map(fn ($index) => strtolower($index->getName()), $indexes); if (in_array('uniq_1483a5e95e237e06', $existingIndexNames, true)) { - $this->addSql('DROP INDEX UNIQ_1483A5E95E237E06 ON Users'); + $this->addSql('DROP INDEX uniq_1483a5e95e237e06'); } if (in_array('uniq_1483a5e9e7927c74', $existingIndexNames, true)) { - $this->addSql('DROP INDEX UNIQ_1483A5E9E7927C74 ON Users'); + $this->addSql('DROP INDEX uniq_1483a5e9e7927c74'); } } } diff --git a/migrations/v1_database_scheme/Users/Version20250705100411_added_some_tables_in_users.php b/migrations/v1_database_scheme/Users/Version20250705100411_added_some_tables_in_users.php index 0e9a76b..0dac741 100644 --- a/migrations/v1_database_scheme/Users/Version20250705100411_added_some_tables_in_users.php +++ b/migrations/v1_database_scheme/Users/Version20250705100411_added_some_tables_in_users.php @@ -11,32 +11,26 @@ final class Version20250705100411Addedsometablesinusers extends AbstractMigratio { public function getDescription(): string { - return 'Adds "is_new", "email_check", "user_country", and "is_lang" columns to the "Users" table, if it exists.'; + return 'Adds "is_new", "email_check", "user_country", and "is_lang" columns to the "users" table, if it exists.'; } public function up(Schema $schema): void { $sm = $this->connection->createSchemaManager(); + if ($sm->tablesExist(['users'])) { + $table = $sm->introspectTable('users'); - if ($sm->tablesExist(['Users'])) { - $table = $sm->introspectTable('Users'); - $sqlParts = []; - - if (! $table->hasColumn('is_new')) { - $sqlParts[] = 'ADD is_new TINYINT(1) NOT NULL'; - } - if (! $table->hasColumn('email_check')) { - $sqlParts[] = 'ADD email_check INT NOT NULL'; + if (!$table->hasColumn('is_new')) { + $this->addSql('ALTER TABLE users ADD COLUMN is_new BOOLEAN NOT NULL'); } - if (! $table->hasColumn('user_country')) { - $sqlParts[] = 'ADD user_country VARCHAR(100) DEFAULT NULL'; + if (!$table->hasColumn('email_check')) { + $this->addSql('ALTER TABLE users ADD COLUMN email_check INTEGER NOT NULL'); } - if (! $table->hasColumn('is_lang')) { - $sqlParts[] = 'ADD is_lang INT NOT NULL'; + if (!$table->hasColumn('user_country')) { + $this->addSql('ALTER TABLE users ADD COLUMN user_country VARCHAR(100) DEFAULT NULL'); } - - if (!empty($sqlParts)) { - $this->addSql('ALTER TABLE Users '.implode(', ', $sqlParts)); + if (!$table->hasColumn('is_lang')) { + $this->addSql('ALTER TABLE users ADD COLUMN is_lang INTEGER NOT NULL'); } } } @@ -45,25 +39,20 @@ public function down(Schema $schema): void { $sm = $this->connection->createSchemaManager(); - if ($sm->tablesExist(['Users'])) { - $table = $sm->introspectTable('Users'); - $sqlParts = []; + if ($sm->tablesExist(['users'])) { + $table = $sm->introspectTable('users'); if ($table->hasColumn('is_new')) { - $sqlParts[] = 'DROP is_new'; + $this->addSql('ALTER TABLE users DROP COLUMN is_new'); } if ($table->hasColumn('email_check')) { - $sqlParts[] = 'DROP email_check'; + $this->addSql('ALTER TABLE users DROP COLUMN email_check'); } if ($table->hasColumn('user_country')) { - $sqlParts[] = 'DROP user_country'; + $this->addSql('ALTER TABLE users DROP COLUMN user_country'); } if ($table->hasColumn('is_lang')) { - $sqlParts[] = 'DROP is_lang'; - } - - if (!empty($sqlParts)) { - $this->addSql('ALTER TABLE Users '.implode(', ', $sqlParts)); + $this->addSql('ALTER TABLE users DROP COLUMN is_lang'); } } } diff --git a/migrations/v1_database_scheme/Users/Version20250802094715.php b/migrations/v1_database_scheme/Users/Version20250802094715.php index eceac0f..dd38f0f 100644 --- a/migrations/v1_database_scheme/Users/Version20250802094715.php +++ b/migrations/v1_database_scheme/Users/Version20250802094715.php @@ -9,46 +9,35 @@ final class Version20250802094715 extends AbstractMigration { - private array $columnsCache = []; - public function getDescription(): string { - return 'Safe migration: modifies tasks, habits, Users and other tables with column existence checks.'; + return 'Safe migration: modifies tasks, habits, users and other tables with column existence checks for PostgreSQL.'; } private function hasColumn(string $table, string $column): bool { - if (!isset($this->columnsCache[$table])) { - $columns = $this->connection - ->fetchAllAssociative("SHOW COLUMNS FROM `$table`"); - - $this->columnsCache[$table] = array_map( - fn ($col) => strtolower($col['Field']), - $columns - ); + $sm = $this->connection->createSchemaManager(); + if (!$sm->tablesExist([$table])) { + return false; } - return in_array(strtolower($column), $this->columnsCache[$table], true); + $columns = $sm->listTableColumns($table); + return isset($columns[$column]); } private function hasIndex(string $table, string $indexName): bool { - $indexes = $this->connection->fetchAllAssociative("SHOW INDEX FROM `$table`"); - - foreach ($indexes as $index) { - if ($index['Key_name'] === $indexName) { - return true; - } + $sm = $this->connection->createSchemaManager(); + if (!$sm->tablesExist([$table])) { + return false; } - return false; + $indexes = $sm->listTableIndexes($table); + return isset($indexes[$indexName]); } public function up(Schema $schema): void { - $platform = $this->connection->getDatabasePlatform()->getName(); - $this->abortIf('mysql' !== $platform, 'Migration supports only MySQL.'); - $tables = [ 'habits', 'tasks', @@ -62,64 +51,62 @@ public function up(Schema $schema): void 'notifications', 'purposes', 'refresh_tokens', - 'Users', + 'users', ]; foreach ($tables as $table) { - if (!$this->hasColumn($table, 'created_at')) { - $this->addSql("ALTER TABLE `$table` ADD created_at DATETIME DEFAULT NULL"); + if ($this->hasColumn($table, 'created_at') === false) { + $this->addSql("ALTER TABLE $table ADD COLUMN created_at TIMESTAMP DEFAULT NULL"); } - if (!$this->hasColumn($table, 'updated_at')) { - $this->addSql("ALTER TABLE `$table` ADD updated_at DATETIME DEFAULT NULL"); + if ($this->hasColumn($table, 'updated_at') === false) { + $this->addSql("ALTER TABLE $table ADD COLUMN updated_at TIMESTAMP DEFAULT NULL"); } - if (!$this->hasColumn($table, 'is_delete')) { - $this->addSql("ALTER TABLE `$table` ADD is_delete TINYINT(1) NOT NULL"); + if ($this->hasColumn($table, 'is_delete') === false) { + $this->addSql("ALTER TABLE $table ADD COLUMN is_delete BOOLEAN NOT NULL DEFAULT FALSE"); } } - if (!$this->hasColumn('matric_column', 'user_id')) { - $this->addSql('ALTER TABLE matric_column ADD user_id INT NOT NULL'); + if ($this->hasColumn('matric_column', 'user_id') === false) { + $this->addSql('ALTER TABLE matric_column ADD COLUMN user_id INTEGER NOT NULL'); } - if (!$this->hasColumn('tasks', 'time')) { + if ($this->hasColumn('tasks', 'time') === false) { $this->addSql('ALTER TABLE tasks - ADD time VARCHAR(255) DEFAULT NULL, - ADD start_date VARCHAR(255) DEFAULT NULL, - ADD start_time VARCHAR(255) DEFAULT NULL, - ADD end_date VARCHAR(255) DEFAULT NULL, - ADD end_time VARCHAR(255) DEFAULT NULL, - ADD repeat_mode VARCHAR(255) DEFAULT NULL + ADD COLUMN time VARCHAR(255) DEFAULT NULL, + ADD COLUMN start_date VARCHAR(255) DEFAULT NULL, + ADD COLUMN start_time VARCHAR(255) DEFAULT NULL, + ADD COLUMN end_date VARCHAR(255) DEFAULT NULL, + ADD COLUMN end_time VARCHAR(255) DEFAULT NULL, + ADD COLUMN repeat_mode VARCHAR(255) DEFAULT NULL '); } if ($this->hasColumn('tasks', 'task_type')) { - $this->addSql('ALTER TABLE tasks DROP task_type'); + $this->addSql('ALTER TABLE tasks DROP COLUMN task_type'); } if ($this->hasColumn('tasks', 'notification_id')) { - $this->addSql('ALTER TABLE tasks DROP notification_id'); + $this->addSql('ALTER TABLE tasks DROP COLUMN notification_id'); } if ($this->hasColumn('tasks', 'due_date')) { - $this->addSql('ALTER TABLE tasks DROP due_date'); + $this->addSql('ALTER TABLE tasks DROP COLUMN due_date'); } - if ($this->hasIndex('tasks_history', 'IDX_USER_ID')) { - $this->addSql('DROP INDEX IDX_USER_ID ON tasks_history'); + if ($this->hasIndex('tasks_history', 'idx_user_id')) { + $this->addSql('DROP INDEX IF EXISTS idx_user_id'); } if ($this->hasColumn('tasks_history', 'tasks_id')) { - $this->addSql("ALTER TABLE tasks_history CHANGE tasks_id tasks_id INT NOT NULL"); + $this->addSql('ALTER TABLE tasks_history ALTER COLUMN tasks_id TYPE INTEGER'); + $this->addSql('ALTER TABLE tasks_history ALTER COLUMN tasks_id SET NOT NULL'); } } public function down(Schema $schema): void { - $platform = $this->connection->getDatabasePlatform()->getName(); - $this->abortIf('mysql' !== $platform, 'Migration supports only MySQL.'); - $tables = [ 'habits', 'tasks', @@ -133,20 +120,20 @@ public function down(Schema $schema): void 'notifications', 'purposes', 'refresh_tokens', - 'Users', + 'users', ]; foreach ($tables as $table) { if ($this->hasColumn($table, 'created_at')) { - $this->addSql("ALTER TABLE `$table` DROP COLUMN created_at"); + $this->addSql("ALTER TABLE $table DROP COLUMN created_at"); } if ($this->hasColumn($table, 'updated_at')) { - $this->addSql("ALTER TABLE `$table` DROP COLUMN updated_at"); + $this->addSql("ALTER TABLE $table DROP COLUMN updated_at"); } if ($this->hasColumn($table, 'is_delete')) { - $this->addSql("ALTER TABLE `$table` DROP COLUMN is_delete"); + $this->addSql("ALTER TABLE $table DROP COLUMN is_delete"); } } @@ -165,24 +152,25 @@ public function down(Schema $schema): void '); } - if (!$this->hasColumn('tasks', 'task_type')) { - $this->addSql('ALTER TABLE tasks ADD task_type VARCHAR(255) DEFAULT NULL'); + if ($this->hasColumn('tasks', 'task_type') === false) { + $this->addSql('ALTER TABLE tasks ADD COLUMN task_type VARCHAR(255) DEFAULT NULL'); } - if (!$this->hasColumn('tasks', 'notification_id')) { - $this->addSql('ALTER TABLE tasks ADD notification_id INT DEFAULT NULL'); + if ($this->hasColumn('tasks', 'notification_id') === false) { + $this->addSql('ALTER TABLE tasks ADD COLUMN notification_id INTEGER DEFAULT NULL'); } - if (!$this->hasColumn('tasks', 'due_date')) { - $this->addSql('ALTER TABLE tasks ADD due_date DATETIME DEFAULT NULL'); + if ($this->hasColumn('tasks', 'due_date') === false) { + $this->addSql('ALTER TABLE tasks ADD COLUMN due_date TIMESTAMP DEFAULT NULL'); } - if (!$this->hasIndex('tasks_history', 'IDX_USER_ID') && $this->hasColumn('tasks_history', 'user_id')) { - $this->addSql('CREATE INDEX IDX_USER_ID ON tasks_history (user_id)'); + if ($this->hasIndex('tasks_history', 'idx_user_id') === false && $this->hasColumn('tasks_history', 'user_id')) { + $this->addSql('CREATE INDEX IF NOT EXISTS idx_user_id ON tasks_history (user_id)'); } if ($this->hasColumn('tasks_history', 'tasks_id')) { - $this->addSql('ALTER TABLE tasks_history CHANGE tasks_id tasks_id INT NOT NULL'); + $this->addSql('ALTER TABLE tasks_history ALTER COLUMN tasks_id TYPE INTEGER'); + $this->addSql('ALTER TABLE tasks_history ALTER COLUMN tasks_id SET NOT NULL'); } } }