Create new table to track geolocation updates

This commit is contained in:
Alejandro Celaya 2024-12-13 10:33:53 +01:00
parent 55724dbff6
commit d4d97c3182
4 changed files with 184 additions and 0 deletions

View File

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\Builder\FieldBuilder;
use Doctrine\ORM\Mapping\ClassMetadata;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
use Shlinkio\Shlink\Core\Geolocation\Entity\GeolocationDbUpdateStatus;
return static function (ClassMetadata $metadata, array $emConfig): void {
$builder = new ClassMetadataBuilder($metadata);
$builder->setTable(determineTableName('geolocation_db_updates', $emConfig));
$builder->createField('id', Types::BIGINT)
->columnName('id')
->makePrimaryKey()
->generatedValue('IDENTITY')
->option('unsigned', true)
->build();
$builder->createField('dateCreated', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('date_created')
->build();
$builder->createField('dateUpdated', ChronosDateTimeType::CHRONOS_DATETIME)
->columnName('date_updated')
->nullable()
->build();
(new FieldBuilder($builder, [
'fieldName' => 'status',
'type' => Types::STRING,
'enumType' => GeolocationDbUpdateStatus::class,
]))->columnName('status')
->length(128)
->build();
fieldWithUtf8Charset($builder->createField('filename', Types::STRING), $emConfig)
->columnName('filename')
->length(512)
->nullable()
->build();
fieldWithUtf8Charset($builder->createField('error', Types::STRING), $emConfig)
->columnName('error')
->length(1024)
->nullable()
->build();
fieldWithUtf8Charset($builder->createField('filesystemId', Types::STRING), $emConfig)
->columnName('filesystem_id')
->length(512)
->build();
// Index on date_updated, as we'll usually sort the query by this field
$builder->addIndex(['date_updated'], 'IDX_geolocation_date_updated');
// Index on status and filesystem_id, as we'll usually filter the query by those fields
$builder->addIndex(['status', 'filesystem_id'], 'IDX_geolocation_status_filesystem');
};

View File

@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace ShlinkMigrations;
use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
/**
* Create a new table to track geolocation db updates
*/
final class Version20241212131058 extends AbstractMigration
{
private const string TABLE_NAME = 'geolocation_db_updates';
public function up(Schema $schema): void
{
$this->skipIf($schema->hasTable(self::TABLE_NAME));
$table = $schema->createTable(self::TABLE_NAME);
$table->addColumn('id', Types::BIGINT, [
'unsigned' => true,
'autoincrement' => true,
'notnull' => true,
]);
$table->setPrimaryKey(['id']);
$table->addColumn('date_created', ChronosDateTimeType::CHRONOS_DATETIME, ['default' => 'CURRENT_TIMESTAMP']);
$table->addColumn('date_updated', ChronosDateTimeType::CHRONOS_DATETIME, ['default' => 'CURRENT_TIMESTAMP']);
$table->addColumn('status', Types::STRING, [
'length' => 128,
'default' => 'in-progress', // in-progress, success, error
]);
$table->addColumn('filesystem_id', Types::STRING, ['length' => 512]);
$table->addColumn('filename', Types::STRING, [
'length' => 512,
'default' => null,
'notnull' => false,
]);
$table->addColumn('error', Types::STRING, [
'length' => 1024,
'default' => null,
'notnull' => false,
]);
// Index on date_updated, as we'll usually sort the query by this field
$table->addIndex(['date_updated'], 'IDX_geolocation_date_updated');
// Index on status and filesystem_id, as we'll usually filter the query by those fields
$table->addIndex(['status', 'filesystem_id'], 'IDX_geolocation_status_filesystem');
}
public function down(Schema $schema): void
{
$this->skipIf(! $schema->hasTable(self::TABLE_NAME));
$schema->dropTable(self::TABLE_NAME);
}
public function isTransactional(): bool
{
return ! ($this->connection->getDatabasePlatform() instanceof MySQLPlatform);
}
}

View File

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Geolocation\Entity;
use Cake\Chronos\Chronos;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use function stat;
class GeolocationDbUpdate extends AbstractEntity
{
private function __construct(
private readonly string $filesystemId,
private GeolocationDbUpdateStatus $status = GeolocationDbUpdateStatus::IN_PROGRESS,
private readonly Chronos $dateCreated = new Chronos(),
private Chronos $dateUpdated = new Chronos(),
private string|null $filename = null,
private string|null $error = null,
) {
}
public static function createForCurrentFilesystem(): self
{
return new self(stat(__FILE__)['dev']);
}
public function finishSuccessfully(string $filename): void
{
$this->dateUpdated = Chronos::now();
$this->filename = $filename;
$this->status = GeolocationDbUpdateStatus::SUCCESS;
}
public function finishWithError(string $error): void
{
$this->dateUpdated = Chronos::now();
$this->error = $error;
$this->status = GeolocationDbUpdateStatus::ERROR;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Shlinkio\Shlink\Core\Geolocation\Entity;
enum GeolocationDbUpdateStatus: string
{
case IN_PROGRESS = 'in-progress';
case SUCCESS = 'success';
case ERROR = 'error';
}