Skip to content

Commit

Permalink
SchemaBuilder Per Connection Grammar (#27)
Browse files Browse the repository at this point in the history
* Create multiple SchemaBuilder implementations per Connection Grammar.

---------

Authored-by: kfriars <[email protected]>
  • Loading branch information
kfriars authored Oct 10, 2024
1 parent 18190a6 commit c65f11e
Show file tree
Hide file tree
Showing 17 changed files with 447 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ return new class extends SnapshotMigration
}
```

You will notice that in a `SnapshotMigration` you have `$this->schema` available which is the `SnapshotSchemaBuilder` instance. It is a wrapper around the framework's `\Illuminate\Database\Schema\Builder` class. You can also use the `SnapshotSchema` facade, however you should only use that inside a `SnapshotMigration`.
You will notice that in a `SnapshotMigration` you have `$this->schema` available which is the `SnapshotBuilder` instance. It is a wrapper around the framework's `\Illuminate\Database\Schema\Builder` class. You can also use the `SnapshotSchema` facade, however you should only use that inside a `SnapshotMigration`.

The `SnapshotMigrations` allow you to declare migrations in the way you are used to, but under the hood it will handle all of the versioning.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
<?php

namespace Plank\Snapshots\Migrator;
namespace Plank\Snapshots\Concerns;

use Closure;
use Illuminate\Database\Connection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Schema\Builder;
use InvalidArgumentException;
use Plank\Snapshots\Contracts\ManagesCreatedTables;
use Plank\Snapshots\Contracts\ManagesVersions;
use Plank\Snapshots\Contracts\Version;
use Plank\Snapshots\Contracts\Versioned;
use Plank\Snapshots\Events\TableCreated;
use Plank\Snapshots\Migrator\SnapshotBlueprint;

/**
* @mixin Builder
*/
class SnapshotSchemaBuilder extends Builder
trait HasVersionedSchema
{
public function __construct(
Connection $connection,
Expand Down Expand Up @@ -170,56 +166,81 @@ public function hasColumns($table, array $columns): bool
/**
* {@inheritDoc}
*/
public function whenTableHasColumn(string $table, string $column, Closure $callback)
public function dropColumns($table, $columns): void
{
if ($this->hasColumn($table, $column)) {
$this->table($table, fn (Blueprint $table) => $callback($table));
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

parent::dropColumns($table, $columns);
}

/**
* {@inheritDoc}
*/
public function whenTableDoesntHaveColumn(string $table, string $column, Closure $callback)
public function getColumnType($table, $column, $fullDefinition = false)
{
if (! $this->hasColumn($table, $column)) {
$this->table($table, fn (Blueprint $table) => $callback($table));
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

return parent::getColumnType($table, $column, $fullDefinition);
}

/**
* {@inheritDoc}
*/
public function dropColumns($table, $columns): void
public function getColumnListing($table): array
{
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

parent::dropColumns($table, $columns);
return parent::getColumnListing($table);
}

/**
* {@inheritDoc}
* Get the columns for a given table.
*
* @param string $table
* @return array
*/
public function getColumnType($table, $column, $fullDefinition = false)
public function getColumns($table)
{
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

return parent::getColumnType($table, $column, $fullDefinition);
return parent::getColumns($table);
}

/**
* {@inheritDoc}
* Get the indexes for a given table.
*
* @param string $table
* @return array
*/
public function getColumnListing($table): array
public function getIndexes($table)
{
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

return parent::getColumnListing($table);
return parent::getIndexes($table);
}

/**
* Get the foreign keys for a given table.
*
* @param string $table
* @return array
*/
public function getForeignKeys($table)
{
if ($active = $this->versions->active()) {
$table = $active->addTablePrefix($table);
}

return parent::getForeignKeys($table);
}
}
23 changes: 23 additions & 0 deletions src/Contracts/VersionedSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Plank\Snapshots\Contracts;

use Closure;

interface VersionedSchema
{
/**
* Create a new table on the schema.
*
* @param class-string<Model> $model
*/
public function createForModel(string $model, Closure $callback): void;

/**
* Create a new table on the schema.
*
* @param class-string<Model> $model
* @param \Closure $callback
*/
public function dropForModel($model): void;
}
10 changes: 8 additions & 2 deletions src/Facades/SnapshotSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Plank\Snapshots\Facades;

use Illuminate\Database\Schema\Builder;
use Illuminate\Database\Schema\ForeignKeyDefinition;
use Illuminate\Database\Schema\IndexDefinition;
use Illuminate\Support\Facades\Facade;
use Plank\Snapshots\Migrator\SnapshotSchemaBuilder;
use Plank\Snapshots\Contracts\VersionedSchema;

/**
* @method static void defaultStringLength(int $length)
Expand All @@ -16,6 +19,8 @@
* @method static bool hasTable(string $table)
* @method static bool hasColumn(string $table, string $column)
* @method static bool hasColumns(string $table, array $columns)
* @method static IndexDefinition[] getIndexes(string $table)
* @method static ForeignKeyDefinition[] getForeignKeys(string $table)
* @method static void whenTableHasColumn(string $table, string $column, \Closure $callback)
* @method static void whenTableDoesntHaveColumn(string $table, string $column, \Closure $callback)
* @method static string getColumnType(string $table, string $column)
Expand All @@ -38,6 +43,7 @@
* @method static \Illuminate\Database\Connection getConnection()
* @method static \Illuminate\Database\Schema\Builder setConnection(\Illuminate\Database\Connection $connection)
* @method static void blueprintResolver(\Closure $resolver)
* @method static Builder&VersionedSchema getFacadeRoot()
*
* @see \Illuminate\Database\Schema\Builder
*/
Expand All @@ -57,6 +63,6 @@ class SnapshotSchema extends Facade
*/
protected static function getFacadeAccessor()
{
return SnapshotSchemaBuilder::class;
return VersionedSchema::class;
}
}
35 changes: 35 additions & 0 deletions src/Factory/SchemaBuilderFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Plank\Snapshots\Factory;

use Illuminate\Database\Connection;
use Illuminate\Database\Schema\Builder;
use Illuminate\Database\Schema\MySqlBuilder;
use Illuminate\Database\Schema\PostgresBuilder;
use Illuminate\Database\Schema\SQLiteBuilder;
use Illuminate\Database\Schema\SqlServerBuilder;
use Plank\Snapshots\Contracts\ManagesCreatedTables;
use Plank\Snapshots\Contracts\ManagesVersions;
use Plank\Snapshots\Contracts\VersionedSchema;
use Plank\Snapshots\Schema\MySqlSnapshotBuilder;
use Plank\Snapshots\Schema\PostgresSnapshotBuilder;
use Plank\Snapshots\Schema\SnapshotBuilder;
use Plank\Snapshots\Schema\SQLiteSnapshotBuilder;
use Plank\Snapshots\Schema\SqlServerSnapshotBuilder;

class SchemaBuilderFactory
{
public static function make(
Connection $connection,
ManagesVersions $versions,
ManagesCreatedTables $tables,
): Builder&VersionedSchema {
return match (get_class($connection->getSchemaBuilder())) {
MySqlBuilder::class => new MySqlSnapshotBuilder($connection, $versions, $tables),
PostgresBuilder::class => new PostgresSnapshotBuilder($connection, $versions, $tables),
SQLiteBuilder::class => new SQLiteSnapshotBuilder($connection, $versions, $tables),
SqlServerBuilder::class => new SqlServerSnapshotBuilder($connection, $versions, $tables),
default => new SnapshotBuilder($connection, $versions, $tables),
};
}
}
4 changes: 3 additions & 1 deletion src/Migrator/SnapshotMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace Plank\Snapshots\Migrator;

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Builder;
use Plank\Snapshots\Contracts\VersionedSchema;
use Plank\Snapshots\Facades\SnapshotSchema;

abstract class SnapshotMigration extends Migration
{
public SnapshotSchemaBuilder $schema;
public Builder&VersionedSchema $schema;

/**
* Create a new migration instance.
Expand Down
12 changes: 12 additions & 0 deletions src/Schema/MySqlSnapshotBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Plank\Snapshots\Schema;

use Illuminate\Database\Schema\MySqlBuilder;
use Plank\Snapshots\Concerns\HasVersionedSchema;
use Plank\Snapshots\Contracts\VersionedSchema;

class MySqlSnapshotBuilder extends MySqlBuilder implements VersionedSchema
{
use HasVersionedSchema;
}
12 changes: 12 additions & 0 deletions src/Schema/PostgresSnapshotBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Plank\Snapshots\Schema;

use Illuminate\Database\Schema\PostgresBuilder;
use Plank\Snapshots\Concerns\HasVersionedSchema;
use Plank\Snapshots\Contracts\VersionedSchema;

class PostgresSnapshotBuilder extends PostgresBuilder implements VersionedSchema
{
use HasVersionedSchema;
}
12 changes: 12 additions & 0 deletions src/Schema/SQLiteSnapshotBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Plank\Snapshots\Schema;

use Illuminate\Database\Schema\SQLiteBuilder;
use Plank\Snapshots\Concerns\HasVersionedSchema;
use Plank\Snapshots\Contracts\VersionedSchema;

class SQLiteSnapshotBuilder extends SQLiteBuilder implements VersionedSchema
{
use HasVersionedSchema;
}
38 changes: 38 additions & 0 deletions src/Schema/SnapshotBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Plank\Snapshots\Schema;

use Illuminate\Database\Schema\Builder;
use Nette\NotImplementedException;
use Plank\Snapshots\Concerns\HasVersionedSchema;
use Plank\Snapshots\Contracts\VersionedSchema;

/**
* @mixin Builder
*/
class SnapshotBuilder extends Builder implements VersionedSchema
{
use HasVersionedSchema;

/**
* Get the indexes for a given table.
*
* @param string $table
* @return array
*/
public function getIndexes($table)
{
throw new NotImplementedException('The `getIndexes` method requires a grammar specific Schema Builder.');
}

/**
* Get the foreign keys for a given table.
*
* @param string $table
* @return array
*/
public function getForeignKeys($table)
{
throw new NotImplementedException('The `getForeignKeys` method requires a grammar specific Schema Builder.');
}
}
12 changes: 12 additions & 0 deletions src/Schema/SqlServerSnapshotBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Plank\Snapshots\Schema;

use Illuminate\Database\Schema\SqlServerBuilder;
use Plank\Snapshots\Concerns\HasVersionedSchema;
use Plank\Snapshots\Contracts\VersionedSchema;

class SqlServerSnapshotBuilder extends SqlServerBuilder implements VersionedSchema
{
use HasVersionedSchema;
}
24 changes: 12 additions & 12 deletions src/SnapshotServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
use Plank\Snapshots\Contracts\ManagesVersions;
use Plank\Snapshots\Contracts\ResolvesCauser;
use Plank\Snapshots\Contracts\Version;
use Plank\Snapshots\Contracts\VersionedSchema;
use Plank\Snapshots\Events\TableCopied;
use Plank\Snapshots\Events\VersionCreated;
use Plank\Snapshots\Exceptions\VersionException;
use Plank\Snapshots\Factory\SchemaBuilderFactory;
use Plank\Snapshots\Migrator\SnapshotMigrator;
use Plank\Snapshots\Migrator\SnapshotSchemaBuilder;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
Expand Down Expand Up @@ -115,19 +116,18 @@ protected function bindRepositories(): self

protected function bindSchemaBuilder(): self
{
if (! $this->app->bound(SnapshotSchemaBuilder::class)) {
$this->app->scoped(SnapshotSchemaBuilder::class, function (Application $app) {
$schema = $this->app['db']->connection()->getSchemaBuilder();
$connection = $schema->getConnection();

return new SnapshotSchemaBuilder(
$connection,
$app[ManagesVersions::class],
$app[ManagesCreatedTables::class]
);
});
if ($this->app->bound(VersionedSchema::class)) {
return $this;
}

$this->app->scoped(VersionedSchema::class, function (Application $app) {
return SchemaBuilderFactory::make(
$app['db.connection'],
$app[ManagesVersions::class],
$app[ManagesCreatedTables::class],
);
});

return $this;
}

Expand Down
Loading

0 comments on commit c65f11e

Please sign in to comment.