Skip to content

Commit

Permalink
Merge pull request #677 from cakephp/import-environment
Browse files Browse the repository at this point in the history
Import additional adapters to setup Environment
  • Loading branch information
markstory authored Jan 13, 2024
2 parents deac137 + 7a154eb commit 1dbfc23
Show file tree
Hide file tree
Showing 10 changed files with 1,628 additions and 0 deletions.
30 changes: 30 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,36 @@ parameters:
count: 1
path: src/Command/BakeMigrationSnapshotCommand.php

-
message: "#^Method Migrations\\\\Db\\\\Adapter\\\\AdapterFactory\\:\\:getAdapter\\(\\) should return Migrations\\\\Db\\\\Adapter\\\\AdapterInterface but returns object\\.$#"
count: 1
path: src/Db/Adapter/AdapterFactory.php

-
message: "#^Unsafe usage of new static\\(\\)\\.$#"
count: 1
path: src/Db/Adapter/AdapterFactory.php

-
message: "#^Call to an undefined method Migrations\\\\Db\\\\Adapter\\\\AdapterInterface\\:\\:getDeleteBuilder\\(\\)\\.$#"
count: 1
path: src/Db/Adapter/AdapterWrapper.php

-
message: "#^Call to an undefined method Migrations\\\\Db\\\\Adapter\\\\AdapterInterface\\:\\:getInsertBuilder\\(\\)\\.$#"
count: 1
path: src/Db/Adapter/AdapterWrapper.php

-
message: "#^Call to an undefined method Migrations\\\\Db\\\\Adapter\\\\AdapterInterface\\:\\:getSelectBuilder\\(\\)\\.$#"
count: 1
path: src/Db/Adapter/AdapterWrapper.php

-
message: "#^Call to an undefined method Migrations\\\\Db\\\\Adapter\\\\AdapterInterface\\:\\:getUpdateBuilder\\(\\)\\.$#"
count: 1
path: src/Db/Adapter/AdapterWrapper.php

-
message: "#^Offset 'id' on non\\-empty\\-array\\<string, mixed\\> in isset\\(\\) always exists and is not nullable\\.$#"
count: 2
Expand Down
20 changes: 20 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
<code><![CDATA[isset($this->output)]]></code>
</RedundantPropertyInitializationCheck>
</file>
<file src="src/Db/Adapter/AdapterWrapper.php">
<InvalidNullableReturnType>
<code>InputInterface</code>
</InvalidNullableReturnType>
<NullableReturnStatement>
<code><![CDATA[$this->adapter->getInput()]]></code>
</NullableReturnStatement>
<UndefinedInterfaceMethod>
<code>getDeleteBuilder</code>
<code>getInsertBuilder</code>
<code>getSelectBuilder</code>
<code>getUpdateBuilder</code>
</UndefinedInterfaceMethod>
</file>
<file src="src/Db/Adapter/MysqlAdapter.php">
<RedundantCondition>
<code>$opened</code>
Expand Down Expand Up @@ -46,6 +60,12 @@
<code>is_array($newColumns)</code>
</RedundantCondition>
</file>
<file src="src/Db/Adapter/TimedOutputAdapter.php">
<MissingParamType>
<code>$columns</code>
<code>$newColumns</code>
</MissingParamType>
</file>
<file src="src/Migration/Manager.php">
<ArgumentTypeCoercion>
<code>array_merge($versions, array_keys($migrations))</code>
Expand Down
172 changes: 172 additions & 0 deletions src/Db/Adapter/AdapterFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php
declare(strict_types=1);

/**
* MIT License
* For full license information, please view the LICENSE file that was distributed with this source code.
*/

namespace Migrations\Db\Adapter;

use RuntimeException;

/**
* Adapter factory and registry.
*
* Used for registering adapters and creating instances of adapters.
*/
class AdapterFactory
{
/**
* @var static|null
*/
protected static ?AdapterFactory $instance = null;

/**
* Get the factory singleton instance.
*
* @return static
*/
public static function instance(): static
{
if (!static::$instance) {
static::$instance = new static();
}

return static::$instance;
}

/**
* Class map of database adapters, indexed by PDO::ATTR_DRIVER_NAME.
*
* @var array<string, \Migrations\Db\Adapter\AdapterInterface|string>
* @phpstan-var array<string, class-string<\Migrations\Db\Adapter\AdapterInterface>>
* @psalm-var array<string, class-string<\Migrations\Db\Adapter\AdapterInterface>>
*/
protected array $adapters = [
'mysql' => MysqlAdapter::class,
'postgres' => PostgresAdapter::class,
'sqlite' => SqliteAdapter::class,
'sqlserver' => SqlserverAdapter::class,
];

/**
* Class map of adapters wrappers, indexed by name.
*
* @var array<string, string>
* @psalm-var array<string, class-string<\Migrations\Db\Adapter\WrapperInterface>>
*/
protected array $wrappers = [
'record' => RecordingAdapter::class,
'timed' => TimedOutputAdapter::class,
];

/**
* Register an adapter class with a given name.
*
* @param string $name Name
* @param string $class Class
* @throws \RuntimeException
* @return $this
*/
public function registerAdapter(string $name, string $class)
{
if (!is_subclass_of($class, AdapterInterface::class)) {
throw new RuntimeException(sprintf(
'Adapter class "%s" must implement Migrations\\Db\\Adapter\\AdapterInterface',
$class
));
}
$this->adapters[$name] = $class;

return $this;
}

/**
* Get an adapter class by name.
*
* @param string $name Name
* @throws \RuntimeException
* @return string
* @phpstan-return class-string<\Migrations\Db\Adapter\AdapterInterface>
*/
protected function getClass(string $name): object|string
{
if (empty($this->adapters[$name])) {
throw new RuntimeException(sprintf(
'Adapter "%s" has not been registered',
$name
));
}

return $this->adapters[$name];
}

/**
* Get an adapter instance by name.
*
* @param string $name Name
* @param array<string, mixed> $options Options
* @return \Migrations\Db\Adapter\AdapterInterface
*/
public function getAdapter(string $name, array $options): AdapterInterface
{
$class = $this->getClass($name);

return new $class($options);
}

/**
* Add or replace a wrapper with a fully qualified class name.
*
* @param string $name Name
* @param string $class Class
* @throws \RuntimeException
* @return $this
*/
public function registerWrapper(string $name, string $class)
{
if (!is_subclass_of($class, WrapperInterface::class)) {
throw new RuntimeException(sprintf(
'Wrapper class "%s" must implement Migrations\\Db\\Adapter\\WrapperInterface',
$class
));
}
$this->wrappers[$name] = $class;

return $this;
}

/**
* Get a wrapper class by name.
*
* @param string $name Name
* @throws \RuntimeException
* @return class-string<\Migrations\Db\Adapter\WrapperInterface>
*/
protected function getWrapperClass(string $name): string
{
if (empty($this->wrappers[$name])) {
throw new RuntimeException(sprintf(
'Wrapper "%s" has not been registered',
$name
));
}

return $this->wrappers[$name];
}

/**
* Get a wrapper instance by name.
*
* @param string $name Name
* @param \Migrations\Db\Adapter\AdapterInterface $adapter Adapter
* @return \Migrations\Db\Adapter\WrapperInterface
*/
public function getWrapper(string $name, AdapterInterface $adapter): WrapperInterface
{
$class = $this->getWrapperClass($name);

return new $class($adapter);
}
}
Loading

0 comments on commit 1dbfc23

Please sign in to comment.