Files
ryobi-crawler/src/Command/Migrate.php

205 lines
7.6 KiB
PHP

<?php
declare(strict_types=1);
namespace Krzysiej\RyobiCrawler\Command;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Schema\Blueprint;
use Krzysiej\RyobiCrawler\Models\Country;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use function Symfony\Component\Clock\now;
#[AsCommand(name: 'app:migrate', description: 'Create database and rum migrations')]
class Migrate extends Command
{
private const RECREATE_OPTION = 'recreate';
protected function configure(): void
{
$this->addOption(self::RECREATE_OPTION, null, InputOption::VALUE_OPTIONAL, 'Recreate database file event if exist and has data.');
}
public function execute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption(self::RECREATE_OPTION)) {
unlink(__DIR__ . '/../../database.sqlite');
touch(__DIR__ . '/../../database.sqlite');
}
$capsule = new Capsule;
$capsule->addConnection([
'driver' => 'sqlite',
'database' => __DIR__ . '/../../database.sqlite',
]);
$capsule->setAsGlobal();
$capsule->bootEloquent();
$this->createProductsTable();
$this->createPricesTable();
$this->createStocksTable();
$this->addColumns();
$this->createCountriesTable();
$this->index();
return Command::SUCCESS;
}
public function createProductsTable(): void
{
if (!Capsule::schema()->hasTable('products')) {
Capsule::schema()->create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->integer('skuID')->unique();
$table->integer('availableQuantity');
$table->json('categories');
$table->string('image');
$table->string('subTitle');
$table->string('variantCode');
$table->string('modelCode');
$table->string('url');
$table->boolean('starred')->default(false);
$table->timestamps();
});
}
}
public function createPricesTable(): void
{
if (!Capsule::schema()->hasTable('prices')) {
Capsule::schema()->create('prices', function (Blueprint $table) {
$table->increments('id');
$table->foreignId('product_id');
$table->float('price');
$table->float('productStandardPrice');
$table->float('lowestProductPrice30Days');
$table->timestamps();
});
}
}
public function createCountriesTable(): void
{
if (!Capsule::schema()->hasTable('countries')) {
Capsule::schema()->create('countries', function (Blueprint $table) {
$table->increments('id');
$table->text('countryName');
$table->text('productsUrl');
$table->text('cultureCode');
$table->text('currency');
$table->text('locale');
$table->timestamps();
});
}
if (Capsule::schema()->hasTable('countries') && !Country::where('countryName', 'Poland')->exists()) {
$id = Capsule::table('countries')->insertGetId(
[
'countryName' => 'Poland',
'productsUrl' => 'https://pl.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'pl-PL',
'currency' => 'PLN',
'locale' => 'pl',
'created_at' => now(),
'updated_at' => now(),
]);
}
if (Capsule::schema()->hasTable('countries') && !Country::where('countryName', 'UK')->exists()) {
Capsule::table('countries')->insert([
'countryName' => 'UK',
'productsUrl' => 'https://uk.ryobitools.eu/api/product-listing/get-products',
'cultureCode' => 'en-GB',
'currency' => 'GBP',
'locale' => 'uk',
'created_at' => now(),
'updated_at' => now(),
]
);
}
if (!Capsule::schema()->hasColumn('products', 'country_id')) {
Capsule::schema()->table('products', function (Blueprint $table) use ($id) {
$table->foreignId('country_id')->default($id)->references('id')->on('countries');
});
}
}
public function createStocksTable(): void
{
if (!Capsule::schema()->hasTable('stocks')) {
Capsule::schema()->create('stocks', function (Blueprint $table) {
$table->increments('id');
$table->foreignId('product_id');
$table->integer('availableQuantity');
$table->integer('stock');
$table->boolean('isInStock');
$table->boolean('previouslyHadStock');
$table->boolean('isNew');
$table->boolean('isComingSoon');
$table->boolean('isOnSale');
$table->timestamps();
});
}
}
public function addColumns(): void
{
if (!Capsule::schema()->hasColumn('products', 'priceCurrent')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->float('priceCurrent')->default(0);
});
}
if (!Capsule::schema()->hasColumn('products', 'priceLowest')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->float('priceLowest')->default(0);
});
}
if (!Capsule::schema()->hasColumn('products', 'productStandardPrice')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->float('productStandardPrice')->default(0);
});
}
if (!Capsule::schema()->hasColumn('products', 'lowestProductPrice30Days')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->float('lowestProductPrice30Days')->default(0);
});
}
if (!Capsule::schema()->hasColumn('products', 'lastSeen')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->date('lastSeen')->nullable();
});
}
if (!Capsule::schema()->hasColumn('products', 'stock')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->integer('stock')->nullable();
});
}
if (!Capsule::schema()->hasColumn('products', 'promotions')) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->json('promotions')->nullable();
});
}
}
public function index(): void
{
if (!count(Capsule::select('SELECT name FROM sqlite_master WHERE type = "index" and name = "products_skuid_country_id_unique"'))) {
Capsule::schema()->table('products', function (Blueprint $table) {
$table->integer('skuID')->unique(false)->change();
$table->unique(['skuID', 'country_id']);
});
}
Capsule::schema()->table('products', function (Blueprint $table) {
$table->foreign('id')->references('product_id')->on('stocks');
});
}
}