Skip to content

Commit

Permalink
Improve "empty" Schema handling
Browse files Browse the repository at this point in the history
  • Loading branch information
chillu committed Feb 5, 2021
1 parent 1f520c0 commit d362065
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
11 changes: 11 additions & 0 deletions src/Dev/Build.php
Expand Up @@ -64,6 +64,17 @@ public function buildSchema($key = null, $clear = false): void
if ($clear) {
$schema->getStore()->clear();
}
$schema->process();

// Allow for "empty" schemas which don't have any types defined.
// This enables baseline configuration of the "default" schema.
if ($schema->exists()) {

} else {
Schema::message('No types defined, skipping');
continue;
}

$schema->save();

Schema::message(
Expand Down
34 changes: 24 additions & 10 deletions src/Schema/Schema.php
Expand Up @@ -41,9 +41,11 @@
use TypeError;

/**
* The main Schema definition. A docking station for all type, model, interface, etc., abstractions.
* The main Schema definition. A docking station for all type, model and interface abstractions.
* Applies plugins, validates, and persists to code.
*
* Use {@link SchemaFactory} to create functional instances of this type
* based on YAML configuration.
*/
class Schema implements ConfigurationApplier, SchemaValidator
{
Expand Down Expand Up @@ -131,16 +133,11 @@ class Schema implements ConfigurationApplier, SchemaValidator
private $schemaContext;

/**
* @var bool See constructor for details about booting.
* @var boolean
*/
private $_booted = false;
private $_isProcessed = false;

/**
* In order to trigger auto-discovery of the schema configuration
* in Silverstripe's config system, call {@link boot()} before using.
* Since booting has a performance impact, some functionality is
* available without booting (e.g. fetching an already persisted schema).
*
* @param string $schemaKey
* @param SchemaContext|null $schemaContext
*/
Expand Down Expand Up @@ -537,9 +534,14 @@ private function collectSchemaUpdaters(array $components): array
}

/**
* @throws SchemaBuilderException
* Process any lazy defined properties (types and modules),
* and execute plugins. This step is automatically taken during {@link save()},
* but can be useful to execute separately in order to determine if the schema
* is valid before saving.
*
* @return void
*/
public function save(): void
public function process(): void
{
// Fill in lazily defined type properties, e.g. fields with a classname as a type
$this->processTypes();
Expand All @@ -561,6 +563,18 @@ public function save(): void
// Resolver discovery
$this->processFields();

$this->_isProcessed = true;
}

/**
* @throws SchemaBuilderException
*/
public function save(): void
{
if (!$this->_isProcessed) {
$this->process();
}

$this->validate();
$this->getStore()->persistSchema($this);

Expand Down
17 changes: 17 additions & 0 deletions src/Schema/SchemaFactory.php
Expand Up @@ -19,6 +19,14 @@ class SchemaFactory
{
use Injectable;

/**
* Retrieves an already stored schema
* which does not require booting.
* Returns null when no stored schema can be found.
*
* @param string $key
* @return Schema|null
*/
public function get(string $key): ?Schema
{
$schema = Schema::create($key);
Expand All @@ -27,6 +35,11 @@ public function get(string $key): ?Schema
}

/**
* Retrieves an already stored schema
* which does not require booting.
* Throws when the schema can either not be found,
* or when it has not been stored yet.
*
* @param string $key
* @return Schema
* @throws SchemaNotFoundException
Expand All @@ -52,6 +65,10 @@ public function require(string $key): Schema
* An instance can only be booted once to avoid conflicts with further
* instance level modifications such as {@link addType()}.
*
* This method should only be used on schemas which have not been stored,
* and is usually only needed for the process of storing them
* (through {@link Schema->save()}).
*
* @param string $key
* @throws SchemaBuilderException
*/
Expand Down

0 comments on commit d362065

Please sign in to comment.