1
0
mirror of https://github.com/flarum/core.git synced 2025-08-06 08:27:42 +02:00
This commit is contained in:
Daniel Klabbers
2021-05-31 15:44:37 +02:00
parent 0727f3d6d4
commit f5c602c234
8 changed files with 214 additions and 50 deletions

View File

@@ -22,7 +22,7 @@ return [
$db = $schema->getConnection();
$db->table('migrations')
->where('permission', 'LIKE', 'viewForum')
->update(['permission' => $db->raw("REPLACE(migration, 'v0.1/', '')")]);
->whereNull('extension')
->update(['migration' => $db->raw("REPLACE('v0.1/', '')")]);
}
];

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Post\Post;
use Flarum\User\User;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\Builder;
return [
'up' => function (Builder $schema) {
$schema->create('discussions', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 200);
$table->unsignedInteger('comments_count')->default(0);
$table->unsignedInteger('participants_count')->default(0);
$table->unsignedInteger('post_number_index')->default(0);
$table->dateTime('created_at');
$table->foreignIdFor(User::class, 'user_id')->nullable();
$table->foreignIdFor(Post::class, 'first_post_id')->nullable();
$table->dateTime('last_posted_at')->nullable();
$table->foreignIdFor(User::class, 'last_posted_user_id')->nullable();
$table->foreignIdFor(Post::class, 'last_post_id')->nullable();
$table->unsignedInteger('last_post_number')->nullable();
$table->dateTime('hidden_at')->nullable();
$table->foreignIdFor(User::class, 'hidden_user_id')->nullable();
$table->string('slug', 200);
$table->boolean('is_private')->default(0);
});
$connection = $schema->getConnection();
$prefix = $connection->getTablePrefix();
$connection->statement('ALTER TABLE '.$prefix.'discussions ADD FULLTEXT title (title)');
},
'down' => function (Builder $schema) {
$schema->drop('discussions');
},
];

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Discussion\Discussion;
use Flarum\User\User;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\Builder;
// We need a full custom migration here, because we need to add the fulltext
// index for the content with a raw SQL statement after creating the table.
return [
'up' => function (Builder $schema) {
$schema->create('posts', function (Blueprint $table) {
$table->increments('id');
$table->foreignIdFor(Discussion::class, 'discussion_id');
$table->unsignedInteger('number')->nullable();
$table->dateTime('created_at');
$table->foreignIdFor(User::class, 'user_id')->nullable();
$table->string('type', 100)->nullable();
$table->mediumText('content')->nullable();
$table->dateTime('edited_at')->nullable();
$table->foreignIdFor(User::class, 'edited_user_id')->nullable();
$table->dateTime('hidden_at')->nullable();
$table->foreignIdFor(User::class, 'hidden_user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->boolean('is_private');
$table->unique(['discussion_id', 'number']);
});
$connection = $schema->getConnection();
$prefix = $connection->getTablePrefix();
$connection->statement('ALTER TABLE '.$prefix.'posts ADD FULLTEXT content (content)');
},
'down' => function (Builder $schema) {
$schema->drop('posts');
}
];

View File

@@ -0,0 +1,19 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Database\Migration;
use Illuminate\Database\Schema\Blueprint;
return Migration::createTable(
'settings',
function (Blueprint $table) {
$table->string('key', 100)->primary();
$table->binary('value')->nullable();
}
);

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Database\Migration;
use Illuminate\Database\Schema\Blueprint;
return Migration::createTable(
'users',
function (Blueprint $table) {
$table->increments('id');
$table->string('username', 100)->unique();
$table->string('email', 150)->unique();
$table->boolean('is_email_confirmed')->default(0);
$table->string('password', 100);
$table->string('avatar_url', 100)->nullable();
$table->text('preferences')->nullable();
$table->dateTime('join_time')->nullable();
$table->dateTime('last_seen_time')->nullable();
$table->dateTime('read_time')->nullable();
$table->dateTime('notification_read_time')->nullable();
$table->integer('discussions_count')->unsigned()->default(0);
$table->integer('comments_count')->unsigned()->default(0);
$table->index('joined_at');
$table->index('last_seen_at');
$table->index('discussion_count');
$table->index('comment_count');
}
);

View File

@@ -12,6 +12,7 @@ namespace Flarum\Database;
use Flarum\Extension\Extension;
use Flarum\Foundation\Application;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Support\Str;
class MigrationSourceRepository
{
@@ -25,31 +26,32 @@ class MigrationSourceRepository
public function flarum(): array
{
if (! $this->databaseVersion()) {
return $this->install();
return $this->wrap($this->install());
}
return $this->upgrade();
return $this->wrap($this->upgrade());
}
public function extension(Extension $extension): ?array
public function extension(Extension $extension): array
{
if (! $extension->hasMigrations()) {
return [];
}
return $extension->getMigrations();
return $this->wrap(glob($extension->getPath().'/migrations/*_*.php'));
}
protected function install(): array
{
// We read every file from the latest major/minor version migrations directory.
// Including the create_<table>_table statements.
$files = glob(__DIR__.'/../../migrations/'.$this->installedVersion(true).'/[0-9_]{15}_*.php');
$files = glob(__DIR__.'/../../migrations/'.$this->installedVersion(true).'/[0-9_]**.php');
// Sort by timestamp.
sort($files);
$create = glob(__DIR__.'/../../migrations/'.$this->installedVersion(true).'/create_*.php');
// Read and prepend the create_<table>_table statements.
$create = glob(__DIR__.'/../../migrations/'.$this->installedVersion(true).'/create_*_table.php');
return array_merge($create, $files);
}
@@ -59,26 +61,28 @@ class MigrationSourceRepository
$files = [];
$add = false;
$directories = glob(__DIR__.'/../../migrations/', GLOB_ONLYDIR);
$directories = glob(__DIR__.'/../../migrations/*', GLOB_ONLYDIR);
sort($directories, SORT_NATURAL);
// Upgrade
// Loop over all version migrations directory until we find the version that is currently active.
foreach ($directories as $directory) {
$directoryVersion = substr(basename($directory), 1);
// We have found the directory matching the version database version. Start adding files.
if (substr($directory, 1) === $this->databaseVersion(true)) {
if ($directoryVersion === $this->databaseVersion(true)) {
$add = true;
}
if ($add) {
// Selectively add files, but only include those matching the format YYYY_MM_DD_HHIISS_<something>.php
// This excludes the create_<table>_table.
$files = array_merge($files, glob(__DIR__."/../../migrations/$directory/[0-9_]{15}_*.php"));
$files = array_merge($files, glob(realpath($directory) . "/[0-9_]**.php"));
}
// Once we found the version that is installed, we can quit.
// Theoretically this should never be necessary, it could just loop over all remaining ones.
if (substr($directory, 1) === $this->installedVersion(true)) {
if ($directoryVersion === $this->installedVersion(true)) {
break;
}
}
@@ -89,6 +93,15 @@ class MigrationSourceRepository
return $files;
}
protected function shortVersion(string $version): string
{
if (preg_match('~(?<version>^[0-9]+\.[0-9]+)~', $version, $m)) {
return $m['version'];
}
return $version;
}
protected function installedVersion(bool $short = false): string
{
$version = Application::VERSION;
@@ -100,15 +113,6 @@ class MigrationSourceRepository
return $version;
}
protected function shortVersion(string $version): string
{
if (preg_match('~(?<version>^[0-9]+\.[0-9]+)~', $version, $m)) {
return $m['version'];
}
return $version;
}
protected function databaseVersion(bool $short = false): ?string
{
$version = $this->connection->getSchemaBuilder()->hasTable('settings')
@@ -121,4 +125,16 @@ class MigrationSourceRepository
return $version;
}
protected function wrap(array $migrations): array
{
return collect($migrations)
->mapWithKeys(function (string $path) {
$path = realpath($path);
$path = Str::after($path, 'migrations/');
$basename = Str::before($path, '.php');
return [$path => $basename];
})
->toArray();
}
}

View File

@@ -11,7 +11,6 @@ namespace Flarum\Database;
use Exception;
use Flarum\Extension\Extension;
use Flarum\Foundation\Application;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Database\Schema\Builder;
use Illuminate\Filesystem\Filesystem;
@@ -79,13 +78,13 @@ class Migrator
/**
* Run the outstanding migrations at a given path.
*
* @param string $path
* @param Extension $extension
* @param string $path
* @param Extension|null $extension
* @return void
*/
public function run($path, Extension $extension = null)
public function run(string $path, Extension $extension = null)
{
$files = $this->getMigrationFiles($path, $extension);
$files = $this->getMigrationFiles($extension);
$ran = $this->repository->getRan($extension ? $extension->getId() : null);
@@ -97,12 +96,12 @@ class Migrator
/**
* Run an array of migrations.
*
* @param string $path
* @param array $migrations
* @param Extension $extension
* @param string $path
* @param array $migrations
* @param Extension|null $extension
* @return void
*/
public function runMigrationList($path, $migrations, Extension $extension = null)
public function runMigrationList(string $path, array $migrations, Extension $extension = null)
{
// First we will just make sure that there are any migrations to run. If there
// aren't, we will just make a note of it to the developer so they're aware
@@ -124,13 +123,13 @@ class Migrator
/**
* Run "up" a migration instance.
*
* @param string $path
* @param string $file
* @param string $path
* @param Extension $extension
* @param string $path
* @param string $file
* @param Extension|null $extension
* @return void
* @throws Exception
*/
protected function runUp($path, $file, Extension $extension = null)
protected function runUp(string $path, string $file, Extension $extension = null)
{
$migration = $this->resolve($path, $file);
@@ -209,14 +208,9 @@ class Migrator
}
}
public function getMigrationFiles(string $path, Extension $extension = null): array
public function getMigrationFiles(Extension $extension = null): array
{
$files = $extension ? $this->source->extension($extension) : $this->source->flarum();
dd($files);
return array_map(function ($file) {
return str_replace('.php', '', basename($file));
}, $files);
return $extension ? $this->source->extension($extension) : $this->source->flarum();
}
/**

View File

@@ -9,6 +9,8 @@
namespace Flarum\Extension;
use Flarum\Database\MigrationSourceRepository;
use Flarum\Database\Migrator;
use Flarum\Extend\LifecycleInterface;
use Flarum\Extension\Exception\ExtensionBootError;
use Illuminate\Contracts\Container\Container;
@@ -458,15 +460,17 @@ class Extension implements Arrayable
}
}
/**
* Retrieves the list of migrations of this extension.
*
* @return array
* @internal
*/
public function getMigrations(): array
public function migrate(Migrator $migrator, string $direction)
{
return glob($this->path.'/migrations/*_*.php');
if (! $this->hasMigrations()) {
return;
}
if ($direction == 'up') {
return $migrator->run($this->getPath().'/migrations', $this);
} else {
return $migrator->reset($this->getPath().'/migrations', $this);
}
}
/**