Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use cake connections pt1 #690

Merged
merged 9 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Command/StatusCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ protected function getConfig(Arguments $args): Config
'host' => $connectionConfig['host'],
'name' => $connectionConfig['database'],
'migration_table' => $table,
'connection' => $connectionName,
];

$configData = [
Expand All @@ -147,7 +148,6 @@ protected function getConfig(Arguments $args): Config
'file' => $templatePath . 'Phinx/create.php.template',
],
'migration_base_class' => 'Migrations\AbstractMigration',
'connection' => ConnectionManager::get($connectionName),
'environment' => $adapterConfig,
// TODO do we want to support the DI container in migrations?
];
Expand Down
8 changes: 8 additions & 0 deletions src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@
return $dropNamespace ? substr((string)strrchr($className, '\\'), 1) : $className;
}

/**
* @inheritdoc
*/
public function getConnection(): string|false

Check warning on line 114 in src/Config/Config.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Config.php#L114

Added line #L114 was not covered by tests
{
return $this->values['connection'] ?? false;

Check warning on line 116 in src/Config/Config.php

View check run for this annotation

Codecov / codecov/patch

src/Config/Config.php#L116

Added line #L116 was not covered by tests
}

/**
* @inheritdoc
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Config/ConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ public function getMigrationPaths(): array;
*/
public function getSeedPaths(): array;

/**
* Get the connection namee
*
* @return string|false
*/
public function getConnection(): string|false;

/**
* Get the template file name.
*
Expand Down
96 changes: 1 addition & 95 deletions src/Db/Adapter/AbstractAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,10 @@ public function setOptions(array $options): AdapterInterface
{
$this->options = $options;

if (isset($options['default_migration_table'])) {
trigger_error('The default_migration_table setting for adapter has been deprecated since 0.13.0. Use `migration_table` instead.', E_USER_DEPRECATED);
if (!isset($options['migration_table'])) {
$options['migration_table'] = $options['default_migration_table'];
}
}

if (isset($options['migration_table'])) {
$this->setSchemaTableName($options['migration_table']);
}

if (isset($options['data_domain'])) {
$this->setDataDomain($options['data_domain']);
}

return $this;
}

Expand Down Expand Up @@ -198,97 +187,14 @@ public function setSchemaTableName(string $schemaTableName)
return $this;
}

/**
* Gets the data domain.
*
* @return array
*/
public function getDataDomain(): array
{
return $this->dataDomain;
}

/**
* Sets the data domain.
*
* @param array $dataDomain Array for the data domain
* @return $this
*/
public function setDataDomain(array $dataDomain)
{
$this->dataDomain = [];

// Iterate over data domain field definitions and perform initial and
// simple normalization. We make sure the definition as a base 'type'
// and it is compatible with the base Phinx types.
foreach ($dataDomain as $type => $options) {
if (!isset($options['type'])) {
throw new InvalidArgumentException(sprintf(
'You must specify a type for data domain type "%s".',
$type
));
}

// Replace type if it's the name of a Phinx constant
if (defined('static::' . $options['type'])) {
$options['type'] = constant('static::' . $options['type']);
}

if (!in_array($options['type'], $this->getColumnTypes(), true)) {
throw new InvalidArgumentException(sprintf(
'An invalid column type "%s" was specified for data domain type "%s".',
$options['type'],
$type
));
}

$internal_type = $options['type'];
unset($options['type']);

// Do a simple replacement for the 'length' / 'limit' option and
// detect hinting values for 'limit'.
if (isset($options['length'])) {
$options['limit'] = $options['length'];
unset($options['length']);
}

if (isset($options['limit']) && !is_numeric($options['limit'])) {
if (!defined('static::' . $options['limit'])) {
throw new InvalidArgumentException(sprintf(
'An invalid limit value "%s" was specified for data domain type "%s".',
$options['limit'],
$type
));
}

$options['limit'] = constant('static::' . $options['limit']);
}

// Save the data domain types in a more suitable format
$this->dataDomain[$type] = [
'type' => $internal_type,
'options' => $options,
];
}

return $this;
}

/**
* @inheritdoc
*/
public function getColumnForType(string $columnName, string $type, array $options): Column
{
$column = new Column();
$column->setName($columnName);

if (array_key_exists($type, $this->getDataDomain())) {
$column->setType($this->dataDomain[$type]['type']);
$column->setOptions($this->dataDomain[$type]['options']);
} else {
$column->setType($type);
}

$column->setType($type);
$column->setOptions($options);

return $column;
Expand Down
12 changes: 11 additions & 1 deletion src/Db/Adapter/PdoAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,17 @@ public function setOptions(array $options): AdapterInterface
parent::setOptions($options);

if (isset($options['connection'])) {
$this->setConnection($options['connection']);
// TODO Change migrations adapters to use the Cake
// Database API instead of PDO.
$driver = $options['connection']->getDriver();

// TODO this is gross and needs to be replaced
$reflect = new ReflectionProperty($driver, 'pdo');
$reflect->setAccessible(true);
$pdo = $reflect->getValue($driver);

assert($pdo instanceof PDO, 'Need a PDO connection');
$this->setConnection($pdo);
}

return $this;
Expand Down
35 changes: 15 additions & 20 deletions src/Migration/Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

namespace Migrations\Migration;

use Cake\Datasource\ConnectionManager;
use Migrations\Db\Adapter\AdapterFactory;
use Migrations\Db\Adapter\AdapterInterface;
use Migrations\Db\Adapter\PhinxAdapter;
use PDO;
use Phinx\Migration\MigrationInterface;
use Phinx\Seed\SeedInterface;
use RuntimeException;
Expand Down Expand Up @@ -340,21 +340,24 @@ public function getAdapter(): AdapterInterface
}

$options = $this->getOptions();
if (isset($options['connection'])) {
if (!($options['connection'] instanceof PDO)) {
throw new RuntimeException('The specified connection is not a PDO instance');
}

$options['connection']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$options['adapter'] = $options['connection']->getAttribute(PDO::ATTR_DRIVER_NAME);
}
if (!isset($options['adapter'])) {
throw new RuntimeException('No adapter was specified for environment: ' . $this->getName());
if (!isset($options['connection'])) {
throw new RuntimeException('No connection defined');
}
// TODO Start here again. Goal is to have Connection go into
// AdapterFactory to choose the adapter.
// Adapters should use Connection API instead of PDO.
$connection = ConnectionManager::get($options['connection']);

// Get the driver classname as those are aligned with adapter names.
$driver = $connection->getDriver();
$driverClass = get_class($driver);
$driverName = strtolower(substr($driverClass, (int)strrpos($driverClass, '\\') + 1));

$options['connection'] = $connection;

$factory = AdapterFactory::instance();
$adapter = $factory
->getAdapter($options['adapter'], $options);
->getAdapter($driverName, $options);

// Automatically time the executed commands
$adapter = $factory->getWrapper('timed', $adapter);
Expand All @@ -375,14 +378,6 @@ public function getAdapter(): AdapterInterface
if ($output) {
$adapter->setOutput($output);
}

// TODO remove this, cake connections don't do prefixes.
// Use the TablePrefixAdapter if table prefix/suffixes are in use
if ($adapter->hasOption('table_prefix') || $adapter->hasOption('table_suffix')) {
$adapter = AdapterFactory::instance()
->getWrapper('prefix', $adapter);
}

$this->setAdapter($adapter);

return $adapter;
Expand Down
47 changes: 0 additions & 47 deletions tests/TestCase/Db/Adapter/MysqlAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -736,53 +736,6 @@ public function testAddColumnWithDefaultLiteral()
$this->assertTrue($rows[1]['Default'] === 'CURRENT_TIMESTAMP' || $rows[1]['Default'] === 'current_timestamp()');
}

public function testAddColumnWithCustomType()
{
$this->adapter->setDataDomain([
'custom1' => [
'type' => 'enum',
'null' => true,
'values' => 'a,b,c',
],
'custom2' => [
'type' => 'enum',
'null' => true,
'values' => ['a', 'b', 'c'],
],
]);

(new Table('table1', [], $this->adapter))
->addColumn('custom1', 'custom1')
->addColumn('custom2', 'custom2')
->addColumn('custom_ext', 'custom2', [
'null' => false,
'values' => ['d', 'e', 'f'],
])
->save();

$this->assertTrue($this->adapter->hasTable('table1'));

$columns = $this->adapter->getColumns('table1');

$this->assertArrayHasKey(1, $columns);
$this->assertArrayHasKey(2, $columns);
$this->assertArrayHasKey(3, $columns);

foreach ([1, 2] as $index) {
$column = $this->adapter->getColumns('table1')[$index];
$this->assertSame("custom{$index}", $column->getName());
$this->assertSame('enum', $column->getType());
$this->assertSame(['a', 'b', 'c'], $column->getValues());
$this->assertTrue($column->getNull());
}

$column = $this->adapter->getColumns('table1')[3];
$this->assertSame('custom_ext', $column->getName());
$this->assertSame('enum', $column->getType());
$this->assertSame(['d', 'e', 'f'], $column->getValues());
$this->assertFalse($column->getNull());
}

public function testAddColumnFirst()
{
$table = new Table('table1', [], $this->adapter);
Expand Down
8 changes: 0 additions & 8 deletions tests/TestCase/Db/Adapter/PdoAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,6 @@ public function testOptions()
$this->assertEquals('bar', $options['foo']);
}

public function testOptionsSetConnection()
{
$connection = $this->getMockBuilder(PDO::class)->disableOriginalConstructor()->getMock();
$this->adapter->setOptions(['connection' => $connection]);

$this->assertSame($connection, $this->adapter->getConnection());
}

public function testOptionsSetSchemaTableName()
{
$this->assertEquals('phinxlog', $this->adapter->getSchemaTableName());
Expand Down
33 changes: 0 additions & 33 deletions tests/TestCase/Db/Adapter/PostgresAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -880,39 +880,6 @@ public function testAddColumnArrayType($column_name, $column_type)
$this->assertTrue($table->hasColumn($column_name));
}

public function testAddColumnWithCustomType()
{
$this->adapter->setDataDomain([
'custom' => [
'type' => 'inet',
'null' => true,
],
]);

(new Table('table1', [], $this->adapter))
->addColumn('custom', 'custom')
->addColumn('custom_ext', 'custom', [
'null' => false,
])
->save();

$this->assertTrue($this->adapter->hasTable('table1'));

$columns = $this->adapter->getColumns('table1');
$this->assertArrayHasKey(1, $columns);
$this->assertArrayHasKey(2, $columns);

$column = $this->adapter->getColumns('table1')[1];
$this->assertSame('custom', $column->getName());
$this->assertSame('inet', $column->getType());
$this->assertTrue($column->getNull());

$column = $this->adapter->getColumns('table1')[2];
$this->assertSame('custom_ext', $column->getName());
$this->assertSame('inet', $column->getType());
$this->assertFalse($column->getNull());
}

public function testRenameColumn()
{
$table = new Table('t', [], $this->adapter);
Expand Down
Loading
Loading