Tables migration, seeders, db dump, README.md

This commit is contained in:
Ilya Rogozhin
2026-06-09 16:21:25 +02:00
parent db1ab73d63
commit 299ab41b7d
10 changed files with 494 additions and 1 deletions
+30 -1
View File
@@ -17,6 +17,10 @@
For Linux env:
```bash
mkdir ilya_test
cd ilya_test
git clone https://gitea.wired-mind.ru/ijin82/test-FHR.git .
cp main-repo/.env.example main-repo/.env
docker compose up
```
@@ -45,4 +49,29 @@ php artisan app:test-fhr-sort
которые потенциально имели опыт с решением подобных задач.
Конечно это решение я в голове не носил, а достал его из гугла.
**Время: 25 минут.**
**Время: 25 минут.**
### Игроки и клубы, миграции, сидирование, выгрузка
```bash
fhr-php
php artisan migrate # Структура БД
# Клубы
php artisan db:seed --class=ClubSeeder
# Игроки
php artisan db:seed --class=PlayerSeeder
```
Выгрузка данных по игрокам и клубам вместе со структурой
```bash
cd /var/lib/mysql-files
mysqldump -u root -psecret test_fhr clubs players > clubs_and_players_dump.sql
```
После такой выгрузки, дамп появится в папке MySQL-files
Тестовый дамп лежит в корне проекта **clubs_and_players_dump.sql**
**Время: 1 час 25 минут.**
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Club extends Model
{
use HasFactory;
//
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Player extends Model
{
use HasFactory;
//
}
@@ -0,0 +1,78 @@
<?php
namespace Database\Factories;
use App\Models\Club;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Club>
*/
class ClubFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
$clubs = [
['ru' => 'Ак Барс', 'en' => 'Ak Bars'],
['ru' => 'Авангард', 'en' => 'Avangard'],
['ru' => 'Салават Юлаев', 'en' => 'Salavat Yulaev'],
['ru' => 'СКА', 'en' => 'SKA'],
['ru' => 'ЦСКА', 'en' => 'CSKA'],
['ru' => 'Металлург', 'en' => 'Metallurg'],
['ru' => 'Динамо', 'en' => 'Dynamo'],
['ru' => 'Локомотив', 'en' => 'Lokomotiv'],
['ru' => 'Трактор', 'en' => 'Traktor'],
['ru' => 'Автомобилист', 'en' => 'Avtomobilist'],
['ru' => 'Торпедо', 'en' => 'Torpedo'],
['ru' => 'Спартак', 'en' => 'Spartak'],
['ru' => 'Северсталь', 'en' => 'Severstal'],
['ru' => 'Амур', 'en' => 'Amur'],
['ru' => 'Адмирал', 'en' => 'Admiral'],
['ru' => 'Сибирь', 'en' => 'Sibir'],
['ru' => 'Барыс', 'en' => 'Barys'],
['ru' => 'Нефтехимик', 'en' => 'Neftekhimik'],
['ru' => 'Куньлунь Ред Стар', 'en' => 'Kunlun Red Star'],
['ru' => 'Витязь', 'en' => 'Vityaz'],
['ru' => 'Сочи', 'en' => 'Sochi'],
['ru' => 'Лада', 'en' => 'Lada'],
];
$cities = [
['ru' => 'Москва', 'en' => 'Moscow'],
['ru' => 'Санкт-Петербург', 'en' => 'St. Petersburg'],
['ru' => 'Казань', 'en' => 'Kazan'],
['ru' => 'Омск', 'en' => 'Omsk'],
['ru' => 'Уфа', 'en' => 'Ufa'],
['ru' => 'Магнитогорск', 'en' => 'Magnitogorsk'],
['ru' => 'Ярославль', 'en' => 'Yaroslavl'],
['ru' => 'Челябинск', 'en' => 'Chelyabinsk'],
['ru' => 'Екатеринбург', 'en' => 'Yekaterinburg'],
['ru' => 'Нижний Новгород', 'en' => 'Nizhny Novgorod'],
['ru' => 'Череповец', 'en' => 'Cherepovets'],
['ru' => 'Хабаровск', 'en' => 'Khabarovsk'],
['ru' => 'Владивосток', 'en' => 'Vladivostok'],
['ru' => 'Новосибирск', 'en' => 'Novosibirsk'],
['ru' => 'Астана', 'en' => 'Astana'],
['ru' => 'Нижнекамск', 'en' => 'Nizhnekamsk'],
['ru' => 'Пекин', 'en' => 'Beijing'],
['ru' => 'Подольск', 'en' => 'Podolsk'],
['ru' => 'Сочи', 'en' => 'Sochi'],
['ru' => 'Тольятти', 'en' => 'Tolyatti'],
];
$club = $clubs[array_rand($clubs)];
$city = $cities[array_rand($cities)];
return [
'name_ru' => $club['ru'],
'name_en' => $club['en'],
'city_ru' => $city['ru'],
'city_en' => $city['en'],
];
}
}
@@ -0,0 +1,151 @@
<?php
namespace Database\Factories;
use App\Models\Player;
use App\Models\Club;
use Illuminate\Database\Eloquent\Factories\Factory;
use Exception;
/**
* @extends Factory<Player>
*/
class PlayerFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
$names = [
['ru' => 'Александр Овечкин', 'en' => 'Alexander Ovechkin'],
['ru' => 'Евгений Малкин', 'en' => 'Evgeni Malkin'],
['ru' => 'Никита Кучеров', 'en' => 'Nikita Kucherov'],
['ru' => 'Артемий Панарин', 'en' => 'Artemi Panarin'],
['ru' => 'Андрей Василевский', 'en' => 'Andrei Vasilevskiy'],
['ru' => 'Илья Ковальчук', 'en' => 'Ilya Kovalchuk'],
['ru' => 'Павел Дацюк', 'en' => 'Pavel Datsyuk'],
['ru' => 'Владимир Тарасенко', 'en' => 'Vladimir Tarasenko'],
['ru' => 'Сергей Бобровский', 'en' => 'Sergei Bobrovsky'],
['ru' => 'Кирилл Капризов', 'en' => 'Kirill Kaprizov'],
['ru' => 'Игорь Шестеркин', 'en' => 'Igor Shesterkin'],
['ru' => 'Илья Сорокин', 'en' => 'Ilya Sorokin'],
['ru' => 'Александр Радулов', 'en' => 'Alexander Radulov'],
['ru' => 'Евгений Кузнецов', 'en' => 'Evgeny Kuznetsov'],
['ru' => 'Дмитрий Орлов', 'en' => 'Dmitry Orlov'],
['ru' => 'Михаил Сергачев', 'en' => 'Mikhail Sergachev'],
['ru' => 'Иван Проворов', 'en' => 'Ivan Provorov'],
['ru' => 'Илья Самсонов', 'en' => 'Ilya Samsonov'],
['ru' => 'Александр Романов', 'en' => 'Alexander Romanov'],
['ru' => 'Андрей Свечников', 'en' => 'Andrei Svechnikov'],
['ru' => 'Евгений Дадонов', 'en' => 'Evgenii Dadonov'],
['ru' => 'Вадим Шипачев', 'en' => 'Vadim Shipachyov'],
['ru' => 'Никита Гусев', 'en' => 'Nikita Gusev'],
['ru' => 'Вячеслав Войнов', 'en' => 'Vyacheslav Voynov'],
['ru' => 'Антон Худобин', 'en' => 'Anton Khudobin'],
['ru' => 'Семен Варламов', 'en' => 'Semyon Varlamov'],
['ru' => 'Валерий Ничушкин', 'en' => 'Valeri Nichushkin'],
['ru' => 'Павел Бучневич', 'en' => 'Pavel Buchnevich'],
['ru' => 'Владислав Гавриков', 'en' => 'Vladislav Gavrikov'],
['ru' => 'Илья Михеев', 'en' => 'Ilya Mikheyev'],
['ru' => 'Денис Гурьянов', 'en' => 'Denis Gurianov'],
['ru' => 'Александр Барабанов', 'en' => 'Alexander Barabanov'],
['ru' => 'Клим Костин', 'en' => 'Klim Kostin'],
['ru' => 'Яков Тренин', 'en' => 'Yakov Trenin'],
['ru' => 'Иван Барбашев', 'en' => 'Ivan Barbashev'],
['ru' => 'Артем Зуб', 'en' => 'Artem Zub'],
['ru' => 'Илья Любушкин', 'en' => 'Ilya Lyubushkin'],
['ru' => 'Александр Георгиев', 'en' => 'Alexandar Georgiev'],
['ru' => 'Петр Кочетков', 'en' => 'Pyotr Kochetkov'],
['ru' => 'Даниил Тарасов', 'en' => 'Daniil Tarasov'],
['ru' => 'Василий Подколзин', 'en' => 'Vasily Podkolzin'],
['ru' => 'Григорий Денисенко', 'en' => 'Grigori Denisenko'],
['ru' => 'Виталий Кравцов', 'en' => 'Vitali Kravtsov'],
['ru' => 'Егор Чинахов', 'en' => 'Yegor Chinakhov'],
['ru' => 'Марат Хуснутдинов', 'en' => 'Marat Khusnutdinov'],
['ru' => 'Шакир Мухамадуллин', 'en' => 'Shakir Mukhamadullin'],
['ru' => 'Александр Алексеев', 'en' => 'Alexander Alexeyev'],
['ru' => 'Даниил Мироманов', 'en' => 'Daniil Miromanov'],
['ru' => 'Дмитрий Воронков', 'en' => 'Dmitri Voronkov'],
['ru' => 'Павел Дорофеев', 'en' => 'Pavel Dorofeyev'],
['ru' => 'Николай Кулемин', 'en' => 'Nikolay Kulemin'],
['ru' => 'Александр Семин', 'en' => 'Alexander Semin'],
['ru' => 'Сергей Федоров', 'en' => 'Sergei Fedorov'],
['ru' => 'Игорь Ларионов', 'en' => 'Igor Larionov'],
['ru' => 'Вячеслав Фетисов', 'en' => 'Viacheslav Fetisov'],
['ru' => 'Павел Буре', 'en' => 'Pavel Bure'],
['ru' => 'Алексей Морозов', 'en' => 'Aleksey Morozov'],
['ru' => 'Данис Зарипов', 'en' => 'Danis Zaripov'],
['ru' => 'Максим Сушинский', 'en' => 'Maxim Sushinsky'],
['ru' => 'Александр Степанов', 'en' => 'Alexander Stepanov'],
['ru' => 'Илья Никулин', 'en' => 'Ilya Nikulin'],
['ru' => 'Алексей Терещенко', 'en' => 'Aleksey Tereshchenko'],
['ru' => 'Сергей Мозякин', 'en' => 'Sergei Mozyakin'],
['ru' => 'Александр Еременко', 'en' => 'Alexander Yeryomenko'],
['ru' => 'Василий Кошечкин', 'en' => 'Vasily Koshechkin'],
['ru' => 'Илья Брызгалов', 'en' => 'Ilya Bryzgalov'],
['ru' => 'Евгений Набоков', 'en' => 'Evgeni Nabokov'],
['ru' => 'Николай Хабибулин', 'en' => 'Nikolai Khabibulin'],
['ru' => 'Алексей Яшин', 'en' => 'Alexei Yashin'],
['ru' => 'Валерий Каменский', 'en' => 'Valeri Kamensky'],
['ru' => 'Алексей Жамнов', 'en' => 'Alexei Zhamnov'],
['ru' => 'Александр Могильный', 'en' => 'Alexander Mogilny'],
['ru' => 'Сергей Макаров', 'en' => 'Sergei Makarov'],
['ru' => 'Владимир Крутов', 'en' => 'Vladimir Krutov'],
['ru' => 'Вячеслав Быков', 'en' => 'Vyacheslav Bykov'],
['ru' => 'Андрей Хомутов', 'en' => 'Andrei Khomutov'],
['ru' => 'Александр Якушев', 'en' => 'Alexander Yakushev'],
['ru' => 'Борис Михайлов', 'en' => 'Boris Mikhailov'],
['ru' => 'Валерий Харламов', 'en' => 'Valeri Kharlamov'],
['ru' => 'Владислав Третьяк', 'en' => 'Vladislav Tretiak'],
['ru' => 'Виктор Тихонов', 'en' => 'Viktor Tikhonov'],
['ru' => 'Всеволод Бобров', 'en' => 'Vsevolod Bobrov'],
['ru' => 'Анатолий Фирсов', 'en' => 'Anatoli Firsov'],
['ru' => 'Владимир Петров', 'en' => 'Vladimir Petrov'],
['ru' => 'Сергей Капустин', 'en' => 'Sergei Kapustin'],
['ru' => 'Виктор Жлуктов', 'en' => 'Viktor Zhluktov'],
['ru' => 'Александр Мальцев', 'en' => 'Alexander Maltsev'],
['ru' => 'Владимир Мышкин', 'en' => 'Vladimir Myshkin'],
['ru' => 'Виктор Коноваленко', 'en' => 'Viktor Konovalenko'],
['ru' => 'Евгений Паладьев', 'en' => 'Yevgeni Paladiev'],
['ru' => 'Юрий Ляпкин', 'en' => 'Yuri Lyapkin'],
['ru' => 'Владимир Шадрин', 'en' => 'Vladimir Shadrin'],
['ru' => 'Александр Гусев', 'en' => 'Alexander Gusev'],
['ru' => 'Валерий Васильев', 'en' => 'Valeri Vasiliev'],
['ru' => 'Геннадий Цыганков', 'en' => 'Gennady Tsygankov'],
['ru' => 'Александр Скворцов', 'en' => 'Alexander Skvortsov'],
['ru' => 'Виктор Тюменев', 'en' => 'Viktor Tyumenev'],
['ru' => 'Сергей Светлов', 'en' => 'Sergei Svetlov'],
['ru' => 'Анатолий Семенов', 'en' => 'Anatoly Semenov'],
['ru' => 'Андрей Ломакин', 'en' => 'Andrei Lomakin'],
];
$name = $names[array_rand($names)];
$club = Club::inRandomOrder()->first();
if (!$club) {
throw new Exception('No clubs found in the database. Please seed the clubs table first.');
}
$usedNumbers = Player::where('club_id', $club->id)->pluck('squad_number')->toArray();
$availableNumbers = array_diff(range(1, 99), $usedNumbers);
if (empty($availableNumbers)) {
throw new Exception("No available squad numbers for club ID: {$club->id}.");
}
$squadNumber = $availableNumbers[array_rand($availableNumbers)];
return [
'full_name_ru' => $name['ru'],
'full_name_en' => $name['en'],
'weight' => rand(65, 105),
'height' => rand(160, 210),
'squad_number' => $squadNumber,
'club_id' => $club->id,
];
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('clubs', function (Blueprint $table) {
$table->id();
$table->string('name_ru');
$table->string('name_en');
$table->string('city_ru');
$table->string('city_en');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('clubs');
}
};
@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('players', function (Blueprint $table) {
$table->id();
$table->string('full_name_ru');
$table->string('full_name_en');
$table->unsignedInteger('weight');
$table->unsignedInteger('height');
$table->tinyInteger('squad_number');
$table->foreignIdFor(\App\Models\Club::class)
->constrained()
->onUpdate('cascade')
->onDelete('restrict');
$table->unique(['club_id', 'squad_number']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('players');
}
};
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace Database\Seeders;
use App\Models\Club;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ClubSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Club::factory()
->count(12)
->create();
}
}
@@ -0,0 +1,20 @@
<?php
namespace Database\Seeders;
use App\Models\Player;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class PlayerSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Player::factory()
->count(30)
->create();
}
}