init
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Migrator;
|
||||
|
||||
if (!defined('ABSPATH')) exit;
|
||||
|
||||
|
||||
use MailPoet\Config\Env;
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoetVendor\Doctrine\DBAL\Connection;
|
||||
use MailPoetVendor\Doctrine\DBAL\Exception;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
|
||||
abstract class DbMigration {
|
||||
/** @var Connection */
|
||||
protected $connection;
|
||||
|
||||
/** @var EntityManager */
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(
|
||||
ContainerWrapper $container
|
||||
) {
|
||||
$this->connection = $container->get(Connection::class);
|
||||
$this->entityManager = $container->get(EntityManager::class);
|
||||
}
|
||||
|
||||
abstract public function run(): void;
|
||||
|
||||
/**
|
||||
* @param class-string<object> $entityClass
|
||||
*/
|
||||
protected function getTableName(string $entityClass): string {
|
||||
return $this->entityManager->getClassMetadata($entityClass)->getTableName();
|
||||
}
|
||||
|
||||
protected function createTable(string $tableName, array $attributes): void {
|
||||
$prefix = Env::$dbPrefix;
|
||||
$charsetCollate = Env::$dbCharsetCollate;
|
||||
$sql = implode(",\n", $attributes);
|
||||
$this->connection->executeStatement("
|
||||
CREATE TABLE IF NOT EXISTS {$prefix}{$tableName} (
|
||||
$sql
|
||||
) {$charsetCollate};
|
||||
");
|
||||
}
|
||||
|
||||
protected function columnExists(string $tableName, string $columnName): bool {
|
||||
global $wpdb;
|
||||
$suppressErrors = $wpdb->suppress_errors();
|
||||
try {
|
||||
$this->connection->executeStatement("SELECT $columnName FROM $tableName LIMIT 0");
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
} finally {
|
||||
$wpdb->suppress_errors($suppressErrors);
|
||||
}
|
||||
}
|
||||
|
||||
protected function tableExists(string $tableName): bool {
|
||||
global $wpdb;
|
||||
$suppressErrors = $wpdb->suppress_errors();
|
||||
try {
|
||||
$this->connection->executeStatement("SELECT 1 FROM $tableName LIMIT 0");
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
} finally {
|
||||
$wpdb->suppress_errors($suppressErrors);
|
||||
}
|
||||
}
|
||||
|
||||
protected function indexExists(string $tableName, string $indexName): bool {
|
||||
global $wpdb;
|
||||
$suppressErrors = $wpdb->suppress_errors();
|
||||
try {
|
||||
$this->connection->executeStatement("ALTER TABLE $tableName ADD INDEX $indexName (__non__existent__column__name__)");
|
||||
} catch (Exception $e) {
|
||||
// Index creating index failed on not existing column we use a fallback. This can happen on MySQL 5.7 and lower and on some MariaDB versions.
|
||||
if ($e->getCode() === 1072) {
|
||||
$database = $wpdb->dbname;
|
||||
$result = $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT count(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = COALESCE(DATABASE(), %s)
|
||||
AND table_name = %s
|
||||
AND index_name = %s",
|
||||
$database,
|
||||
$tableName,
|
||||
$indexName
|
||||
));
|
||||
|
||||
return $result > 0;
|
||||
}
|
||||
// Index exists when the error message contains its name. Otherwise, it's the non-existent column error.
|
||||
return strpos($e->getMessage(), $indexName) !== false;
|
||||
} finally {
|
||||
$wpdb->suppress_errors($suppressErrors);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user