Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ryangjchandler committed Oct 3, 2023
1 parent 3adfd16 commit 63a8596
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 23 deletions.
18 changes: 8 additions & 10 deletions src/Actions/InitialiseOrbitalTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Orbit\Contracts\Orbit;
use Orbit\Support\ConfigureBlueprintFromModel;
use Orbit\Support\ModelUsesSoftDeletes;
use ReflectionClass;

class InitialiseOrbitalTable
{
public function shouldInitialise(Orbit&Model $model): bool
{
$schemaBuilder = $model->resolveConnection()->getSchemaBuilder();

return $schemaBuilder->hasTable($model->getTable());
$modelFile = (new ReflectionClass($model))->getFileName();
$modelFileMTime = filemtime($modelFile);
$databaseMTime = filemtime(config('orbit.paths.database'));

return ($modelFileMTime > $databaseMTime) || !$schemaBuilder->hasTable($model->getTable());
}

public function migrate(Orbit&Model $model): void
Expand All @@ -30,15 +36,7 @@ public function migrate(Orbit&Model $model): void
$schemaBuilder->create($table, static function (Blueprint $table) use (&$blueprint, $model) {
$blueprint = $table;

$model->schema($blueprint);

if ($model->usesTimestamps()) {
$blueprint->timestamps();
}

if (ModelUsesSoftDeletes::check($model)) {
$blueprint->softDeletes();
}
ConfigureBlueprintFromModel::configure($model, $blueprint);
});
}
}
28 changes: 19 additions & 9 deletions src/Actions/MaybeRefreshDatabaseContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@

use FilesystemIterator;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Collection;
use Orbit\Contracts\Driver;
use Orbit\Contracts\Orbit;
use Orbit\Support\ConfigureBlueprintFromModel;
use Orbit\Support\FillMissingAttributeValues;
use Orbit\Support\FillMissingAttributeValuesFromBlueprint;
use ReflectionClass;

class MaybeRefreshDatabaseContent
Expand All @@ -18,37 +22,43 @@ public function shouldRefresh(Orbit&Model $model): bool
$highestMTime = 0;

foreach (new FilesystemIterator($directory, FilesystemIterator::SKIP_DOTS) as $file) {
if ($file->getMTime() > $highestMTime) {
if ($file->getMTime() >= $highestMTime) {
$highestMTime = $file->getMTime();
}
}

return $highestMTime > $databaseMTime;
return $highestMTime >= $databaseMTime;
}

public function refresh(Orbit&Model $model, Driver $driver): void
{
$databaseMTime = filemtime(config('orbit.paths.database'));
$model->query()->truncate();

$directory = config('orbit.paths.content').DIRECTORY_SEPARATOR.$model->getOrbitSource();
$iterator = new FilesystemIterator($directory, FilesystemIterator::SKIP_DOTS);
$records = [];

foreach ($iterator as $file) {
if ($file->getMTime() <= $databaseMTime) {
continue;
}

$contents = file_get_contents($file->getRealPath());
$records[] = $driver->parse($contents);
}

$blueprint = ConfigureBlueprintFromModel::configure(
$model,
new Blueprint($model->getTable())
);

collect($records)
->chunk(100)
->each(function (Collection $chunk) use ($model) {
->each(function (Collection $chunk) use ($model, $blueprint) {
// This will ensure that we don't have any collisions with existing data in the SQLite database.
$model->query()->whereKey($chunk->pluck($model->getKey()))->delete();
$model->insert($chunk->all());

$model->insert(
$chunk
->map(fn (array $attributes) => FillMissingAttributeValuesFromBlueprint::fill($attributes, $blueprint))
->all()
);
});
}
}
6 changes: 5 additions & 1 deletion src/Actions/SaveCompiledAttributesToFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ public function execute(Orbit&Model $model, string $compiledAttributes, Driver $
{
$directory = config('orbit.paths.content').DIRECTORY_SEPARATOR.$model->getOrbitSource();
$filename = "{$model->getKey()}.{$driver->extension()}";

$fs = new Filesystem();

if ($model->wasChanged($model->getKey())) {
$fs->delete($directory . DIRECTORY_SEPARATOR . $model->getOriginal($model->getKeyName()) . '.' . $driver->extension());
}

$fs->put($directory.DIRECTORY_SEPARATOR.$filename, $compiledAttributes);
}
}
4 changes: 2 additions & 2 deletions src/Concerns/Orbital.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ public static function bootOrbital()
$initialiseOrbitTable->migrate($model);
}

$saveCompiledAttributesToFile = new SaveCompiledAttributesToFile();

$maybeRefreshDatabaseContent = new MaybeRefreshDatabaseContent();

if ($maybeRefreshDatabaseContent->shouldRefresh($model)) {
$maybeRefreshDatabaseContent->refresh($model, $driver);
}

$saveCompiledAttributesToFile = new SaveCompiledAttributesToFile();

static::created(function (Orbit&Model $model) use ($driver, $saveCompiledAttributesToFile) {
$model->refresh();

Expand Down
25 changes: 25 additions & 0 deletions src/Support/ConfigureBlueprintFromModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Orbit\Support;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Orbit\Contracts\Orbit;

class ConfigureBlueprintFromModel
{
public static function configure(Orbit & Model $model, Blueprint $blueprint): Blueprint
{
$model->schema($blueprint);

if ($model->usesTimestamps()) {
$blueprint->timestamps();
}

if (ModelUsesSoftDeletes::check($model)) {
$blueprint->softDeletes();
}

return $blueprint;
}
}
29 changes: 29 additions & 0 deletions src/Support/FillMissingAttributeValuesFromBlueprint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Orbit\Support;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Orbit\Contracts\Orbit;

class FillMissingAttributeValuesFromBlueprint
{
public static function fill(array $attributes, Blueprint $blueprint): array
{
foreach ($blueprint->getColumns() as $column) {
$name = $column->name;

Check failure on line 14 in src/Support/FillMissingAttributeValuesFromBlueprint.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property Illuminate\Database\Schema\ColumnDefinition::$name.

if (array_key_exists($name, $attributes)) {
continue;
}

if ($column->nullable) {

Check failure on line 20 in src/Support/FillMissingAttributeValuesFromBlueprint.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property Illuminate\Database\Schema\ColumnDefinition::$nullable.
$attributes[$name] = null;
} elseif ($column->default) {

Check failure on line 22 in src/Support/FillMissingAttributeValuesFromBlueprint.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property Illuminate\Database\Schema\ColumnDefinition::$default.
$attributes[$name] = $column->default;
}
}

return $attributes;
}
}
1 change: 1 addition & 0 deletions tests/Fixtures/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public function schema(Blueprint $table): void
{
$table->id();
$table->string('title');
$table->longText('content')->nullable();
}
}
2 changes: 1 addition & 1 deletion tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

uses(Tests\TestCase::class)->in('Feature');

beforeEach(function () {
afterEach(function () {
Post::all()->each(fn (Post $post) => $post->delete());
Category::all()->each(fn (Category $category) => $category->forceDelete());
});

0 comments on commit 63a8596

Please sign in to comment.