summaryrefslogtreecommitdiff
path: root/src/Database/Migration
diff options
context:
space:
mode:
Diffstat (limited to 'src/Database/Migration')
-rw-r--r--src/Database/Migration/Migrate.php192
-rw-r--r--src/Database/Migration/Migration.php16
-rw-r--r--src/Database/Migration/MigrationServiceProvider.php20
3 files changed, 228 insertions, 0 deletions
diff --git a/src/Database/Migration/Migrate.php b/src/Database/Migration/Migrate.php
new file mode 100644
index 00000000..3a08bb6e
--- /dev/null
+++ b/src/Database/Migration/Migrate.php
@@ -0,0 +1,192 @@
+<?php
+
+namespace Engelsystem\Database\Migration;
+
+use Engelsystem\Application;
+use Illuminate\Database\Query\Builder;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Schema\Builder as SchemaBuilder;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Str;
+
+class Migrate
+{
+ const UP = 'up';
+ const DOWN = 'down';
+
+ /** @var Application */
+ protected $app;
+
+ /** @var SchemaBuilder */
+ protected $scheme;
+
+ /** @var callable */
+ protected $output;
+
+ /** @var string */
+ protected $table = 'migrations';
+
+ /**
+ * Migrate constructor
+ *
+ * @param SchemaBuilder $scheme
+ * @param Application $app
+ */
+ public function __construct(SchemaBuilder $scheme, Application $app)
+ {
+ $this->app = $app;
+ $this->scheme = $scheme;
+ $this->output = function () { };
+ }
+
+ /**
+ * Run a migration
+ *
+ * @param string $path
+ * @param string $type (up|down)
+ * @param bool $oneStep
+ */
+ public function run($path, $type = self::UP, $oneStep = false)
+ {
+ $this->initMigration();
+ $migrations = $this->getMigrations($path);
+ $migrated = $this->getMigrated();
+
+ if ($type == self::DOWN) {
+ $migrations = array_reverse($migrations, true);
+ }
+
+ foreach ($migrations as $file => $migration) {
+ if (
+ ($type == self::UP && $migrated->contains('migration', $migration))
+ || ($type == self::DOWN && !$migrated->contains('migration', $migration))
+ ) {
+ call_user_func($this->output, 'Skipping ' . $migration);
+ continue;
+ }
+
+ call_user_func($this->output, 'Migrating ' . $migration . ' (' . $type . ')');
+
+ $this->migrate($file, $migration, $type);
+ $this->setMigrated($migration, $type);
+
+ if ($oneStep) {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Get all migrated migrations
+ *
+ * @return Collection
+ */
+ protected function getMigrated()
+ {
+ return $this->getTableQuery()->get();
+ }
+
+ /**
+ * Migrate a migration
+ *
+ * @param string $file
+ * @param string $migration
+ * @param string $type (up|down)
+ */
+ protected function migrate($file, $migration, $type = self::UP)
+ {
+ require_once $file;
+
+ $className = Str::studly(preg_replace('/\d+_/', '', $migration));
+ /** @var Migration $class */
+ $class = $this->app->make($className);
+
+ if (method_exists($class, $type)) {
+ $class->{$type}();
+ }
+ }
+
+ /**
+ * Set a migration to migrated
+ *
+ * @param string $migration
+ * @param string $type (up|down)
+ */
+ protected function setMigrated($migration, $type = self::UP)
+ {
+ $table = $this->getTableQuery();
+
+ if ($type == self::DOWN) {
+ $table->where(['migration' => $migration])->delete();
+ return;
+ }
+
+ $table->insert(['migration' => $migration]);
+ }
+
+ /**
+ * Get a list of migration files
+ *
+ * @param string $dir
+ * @return array
+ */
+ protected function getMigrations($dir)
+ {
+ $files = $this->getMigrationFiles($dir);
+
+ $migrations = [];
+ foreach ($files as $dir) {
+ $name = str_replace('.php', '', basename($dir));
+ $migrations[$dir] = $name;
+ }
+
+ asort($migrations);
+ return $migrations;
+ }
+
+ /**
+ * List all migration files from the given directory
+ *
+ * @param string $dir
+ * @return array
+ */
+ protected function getMigrationFiles($dir)
+ {
+ return glob($dir . '/*_*.php');
+ }
+
+ /**
+ * Setup migration tables
+ */
+ protected function initMigration()
+ {
+ if ($this->scheme->hasTable($this->table)) {
+ return;
+ }
+
+ $this->scheme->create($this->table, function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('migration');
+ });
+ }
+
+ /**
+ * Init a table query
+ *
+ * @return Builder
+ */
+ protected function getTableQuery()
+ {
+ return $this->scheme->getConnection()->table($this->table);
+ }
+
+ /**
+ * Set the output function
+ *
+ * @param callable $output
+ */
+ public function setOutput(callable $output)
+ {
+ $this->output = $output;
+ }
+}
diff --git a/src/Database/Migration/Migration.php b/src/Database/Migration/Migration.php
new file mode 100644
index 00000000..fcc57b82
--- /dev/null
+++ b/src/Database/Migration/Migration.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Engelsystem\Database\Migration;
+
+use Illuminate\Database\Schema\Builder as SchemaBuilder;
+
+abstract class Migration
+{
+ /** @var SchemaBuilder */
+ protected $schema;
+
+ public function __construct(SchemaBuilder $schemaBuilder)
+ {
+ $this->schema = $schemaBuilder;
+ }
+}
diff --git a/src/Database/Migration/MigrationServiceProvider.php b/src/Database/Migration/MigrationServiceProvider.php
new file mode 100644
index 00000000..15d06eaf
--- /dev/null
+++ b/src/Database/Migration/MigrationServiceProvider.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Engelsystem\Database\Migration;
+
+use Engelsystem\Container\ServiceProvider;
+use Engelsystem\Database\Db;
+use Illuminate\Database\Schema\Builder as SchemaBuilder;
+
+class MigrationServiceProvider extends ServiceProvider
+{
+ public function register()
+ {
+ $schema = Db::connection()->getSchemaBuilder();
+ $this->app->instance('db.scheme', $schema);
+ $this->app->bind(SchemaBuilder::class, 'db.scheme');
+
+ $migration = $this->app->make(Migrate::class);
+ $this->app->instance('db.migration', $migration);
+ }
+}