From 81d7223d4d285d579df78b8dd49c6151e6a5206a Mon Sep 17 00:00:00 2001 From: Nathan Page Date: Wed, 17 Mar 2021 22:44:25 +1100 Subject: [PATCH] [EasyWebhook] Refactor statements provider to use dbal schema (#501) --- .../Doctrine/DbalStatementsProvider.php | 152 ++++++++++++++++++ .../StatementsProviderInterface.php | 18 --- .../SqlStatementProvider.php | 60 ------- .../SqliteStatementProvider.php | 61 ------- .../src/Interfaces/Stores/StoreInterface.php | 5 + .../src/Stores/DoctrineDbalStore.php | 1 + .../tests/AbstractStoreTestCase.php | 20 ++- 7 files changed, 175 insertions(+), 142 deletions(-) create mode 100644 packages/EasyWebhook/src/Bridge/Doctrine/DbalStatementsProvider.php delete mode 100644 packages/EasyWebhook/src/Bridge/Doctrine/Interfaces/StatementsProviderInterface.php delete mode 100644 packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqlStatementProvider.php delete mode 100644 packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqliteStatementProvider.php diff --git a/packages/EasyWebhook/src/Bridge/Doctrine/DbalStatementsProvider.php b/packages/EasyWebhook/src/Bridge/Doctrine/DbalStatementsProvider.php new file mode 100644 index 000000000..690f8022f --- /dev/null +++ b/packages/EasyWebhook/src/Bridge/Doctrine/DbalStatementsProvider.php @@ -0,0 +1,152 @@ +conn = $conn; + $this->webhooksTable = $webhooksTable ?? StoreInterface::DEFAULT_TABLE; + $this->webhookResultsTable = $webhookResultsTable ?? ResultStoreInterface::DEFAULT_TABLE; + } + + public function extendWebhookResultsTable(callable $callable): self + { + $this->extendWebhookResultsTable = $callable; + + return $this; + } + + public function extendWebhooksTable(callable $callable): self + { + $this->extendWebhooksTable = $callable; + + return $this; + } + + /** + * @return string[] + * + * @throws \Doctrine\DBAL\Exception + */ + public function migrateStatements(): array + { + $schema = new Schema(); + + $webhooksTable = $schema->createTable($this->webhooksTable); + $webhooksTable->addColumn('id', 'guid'); + $webhooksTable->addColumn('class', 'string', [ + 'length' => 191, + ]); + $webhooksTable->addColumn('method', 'string', [ + 'length' => 10, + ]); + $webhooksTable->addColumn('url', 'string', [ + 'length' => 191, + ]); + $webhooksTable->addColumn('status', 'string', [ + 'length' => 50, + ]); + $webhooksTable->addColumn('event', 'string', [ + 'length' => 191, + 'notNull' => false, + ]); + $webhooksTable->addColumn('http_options', 'text', [ + 'notNull' => false, + ]); + $webhooksTable->addColumn('current_attempt', 'integer', [ + 'default' => 0, + 'length' => 11, + ]); + $webhooksTable->addColumn('max_attempt', 'integer', [ + 'default' => 1, + 'length' => 11, + ]); + $webhooksTable->addColumn('send_after', 'datetime', [ + 'notNull' => false, + ]); + $webhooksTable->addColumn('created_at', 'datetime'); + $webhooksTable->addColumn('updated_at', 'datetime'); + $webhooksTable->setPrimaryKey(['id']); + $webhooksTable->addIndex(['status', 'send_after'], 'send_after_idx'); + + $webhookResultsTable = $schema->createTable($this->webhookResultsTable); + $webhookResultsTable->addColumn('id', 'guid'); + $webhookResultsTable->addColumn('method', 'string', [ + 'length' => 10, + ]); + $webhookResultsTable->addColumn('url', 'string'); + $webhookResultsTable->addColumn('http_options', 'text', [ + 'notNull' => false, + ]); + $webhookResultsTable->addColumn('response', 'text', [ + 'notNull' => false, + ]); + $webhookResultsTable->addColumn('throwable', 'text', [ + 'notNull' => false, + ]); + $webhookResultsTable->addColumn('webhook_class', 'string', [ + 'length' => 191, + ]); + $webhookResultsTable->addColumn('webhook_id', 'guid'); + $webhookResultsTable->addColumn('created_at', 'datetime'); + $webhookResultsTable->addColumn('updated_at', 'datetime'); + $webhookResultsTable->setPrimaryKey(['id']); + + if ($this->extendWebhooksTable !== null) { + \call_user_func($this->extendWebhooksTable, $webhooksTable); + } + + if ($this->extendWebhookResultsTable !== null) { + \call_user_func($this->extendWebhookResultsTable, $webhookResultsTable); + } + + return $schema->toSql($this->conn->getDatabasePlatform()); + } + + /** + * @return string[] + * + * @throws \Doctrine\DBAL\Exception + */ + public function rollbackStatements(): array + { + return [ + \sprintf('DROP TABLE %s;', $this->webhookResultsTable), + \sprintf('DROP TABLE %s;', $this->webhooksTable), + ]; + } +} diff --git a/packages/EasyWebhook/src/Bridge/Doctrine/Interfaces/StatementsProviderInterface.php b/packages/EasyWebhook/src/Bridge/Doctrine/Interfaces/StatementsProviderInterface.php deleted file mode 100644 index 00deebda4..000000000 --- a/packages/EasyWebhook/src/Bridge/Doctrine/Interfaces/StatementsProviderInterface.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ - public static function migrateStatements(): iterable; - - /** - * @return iterable - */ - public static function rollbackStatements(): iterable; -} diff --git a/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqlStatementProvider.php b/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqlStatementProvider.php deleted file mode 100644 index dc98ee411..000000000 --- a/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqlStatementProvider.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ - public static function migrateStatements(): iterable - { - yield ' - CREATE TABLE `easy_webhooks` ( - `id` CHAR(36) NOT NULL COMMENT "(DC2Type:guid)", - `method` VARCHAR(10) NOT NULL, - `url` VARCHAR(191) NOT NULL, - `status` VARCHAR(50) NOT NULL, - `event` VARCHAR(191) DEFAULT NULL, - `current_attempt` INT(11) DEFAULT 0 NOT NULL, - `max_attempt` INT(11) DEFAULT 0 NOT NULL, - `send_after` DATETIME DEFAULT NULL, - `class` VARCHAR(191) NOT NULL, - `created_at` DATETIME DEFAULT NULL, - `updated_at` DATETIME DEFAULT NULL, - PRIMARY KEY (`id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - '; - - yield 'CREATE INDEX send_after_idx ON `easy_webhooks` (`status`, `send_after`)'; - - yield ' - CREATE TABLE `easy_webhook_results` ( - `id` CHAR(36) NOT NULL COMMENT "(DC2Type:guid)", - `method` VARCHAR(10) NOT NULL, - `url` VARCHAR(191) NOT NULL, - `http_options` LONGTEXT DEFAULT NULL, - `response` LONGTEXT DEFAULT NULL, - `throwable` LONGTEXT DEFAULT NULL, - `webhook_class` VARCHAR(191) NOT NULL, - `webhook_id` CHAR(36) NOT NULL, - `created_at` DATETIME DEFAULT NULL, - `updated_at` DATETIME DEFAULT NULL, - PRIMARY KEY(`id`) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - '; - } - - /** - * @return iterable - */ - public static function rollbackStatements(): iterable - { - yield 'DROP TABLE `easy_webhook_results`;'; - yield 'DROP TABLE `easy_webhooks`;'; - } -} diff --git a/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqliteStatementProvider.php b/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqliteStatementProvider.php deleted file mode 100644 index 52f2e1d45..000000000 --- a/packages/EasyWebhook/src/Bridge/Doctrine/StatementProviders/SqliteStatementProvider.php +++ /dev/null @@ -1,61 +0,0 @@ - - */ - public static function migrateStatements(): iterable - { - yield ' - CREATE TABLE `easy_webhooks` ( - `id` CHAR(36) NOT NULL, - `method` VARCHAR(10) NOT NULL, - `url` VARCHAR(191) NOT NULL, - `status` VARCHAR(50) NOT NULL, - `event` VARCHAR(191) DEFAULT NULL, - `http_options` LONGTEXT DEFAULT NULL, - `current_attempt` INT(11) DEFAULT 0 NOT NULL, - `max_attempt` INT(11) DEFAULT 0 NOT NULL, - `send_after` DATETIME DEFAULT NULL, - `class` VARCHAR(191) NOT NULL, - `created_at` DATETIME DEFAULT NULL, - `updated_at` DATETIME DEFAULT NULL, - PRIMARY KEY (`id`) - ); - '; - - yield 'CREATE INDEX send_after_idx ON `easy_webhooks` (`status`, `send_after`)'; - - yield ' - CREATE TABLE `easy_webhook_results` ( - `id` CHAR(36) NOT NULL, - `method` VARCHAR(10) NOT NULL, - `url` VARCHAR(191) NOT NULL, - `http_options` LONGTEXT DEFAULT NULL, - `response` LONGTEXT DEFAULT NULL, - `throwable` LONGTEXT DEFAULT NULL, - `webhook_class` VARCHAR(191) NOT NULL, - `webhook_id` CHAR(36) NOT NULL, - `created_at` DATETIME DEFAULT NULL, - `updated_at` DATETIME DEFAULT NULL, - PRIMARY KEY (`id`) - ); - '; - } - - /** - * @return iterable - */ - public static function rollbackStatements(): iterable - { - yield 'DROP TABLE `easy_webhook_results`;'; - yield 'DROP TABLE `easy_webhooks`;'; - } -} diff --git a/packages/EasyWebhook/src/Interfaces/Stores/StoreInterface.php b/packages/EasyWebhook/src/Interfaces/Stores/StoreInterface.php index 736ef5a0f..0845aa14e 100644 --- a/packages/EasyWebhook/src/Interfaces/Stores/StoreInterface.php +++ b/packages/EasyWebhook/src/Interfaces/Stores/StoreInterface.php @@ -13,6 +13,11 @@ interface StoreInterface */ public const DATETIME_FORMAT = 'Y-m-d H:i:s'; + /** + * @var string + */ + public const DEFAULT_TABLE = 'easy_webhooks'; + public function find(string $id): ?WebhookInterface; public function generateWebhookId(): string; diff --git a/packages/EasyWebhook/src/Stores/DoctrineDbalStore.php b/packages/EasyWebhook/src/Stores/DoctrineDbalStore.php index 6ca5969ab..f6ef4df90 100644 --- a/packages/EasyWebhook/src/Stores/DoctrineDbalStore.php +++ b/packages/EasyWebhook/src/Stores/DoctrineDbalStore.php @@ -84,6 +84,7 @@ public function store(WebhookInterface $webhook): WebhookInterface $now = Carbon::now('UTC'); $data = \array_merge($webhook->getExtra() ?? [], $webhook->toArray()); $data['class'] = \get_class($webhook); + $data['updated_at'] = $now; // New result with no id if ($webhook->getId() === null) { diff --git a/packages/EasyWebhook/tests/AbstractStoreTestCase.php b/packages/EasyWebhook/tests/AbstractStoreTestCase.php index 8f5b48e8d..9ad5ac3a8 100644 --- a/packages/EasyWebhook/tests/AbstractStoreTestCase.php +++ b/packages/EasyWebhook/tests/AbstractStoreTestCase.php @@ -6,7 +6,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\DriverManager; -use EonX\EasyWebhook\Bridge\Doctrine\StatementProviders\SqliteStatementProvider; +use EonX\EasyWebhook\Bridge\Doctrine\DbalStatementsProvider; use EonX\EasyWebhook\Interfaces\WebhookInterface; use EonX\EasyWebhook\Webhook; @@ -17,6 +17,11 @@ abstract class AbstractStoreTestCase extends AbstractTestCase */ protected $doctrineDbal; + /** + * @var \EonX\EasyWebhook\Bridge\Doctrine\DbalStatementsProvider + */ + private $stmtsProvider; + protected function createWebhookForSendAfter( ?\DateTimeInterface $sendAfter = null, ?string $status = null @@ -53,7 +58,7 @@ protected function setUp(): void $conn = $this->getDoctrineDbalConnection(); $conn->connect(); - foreach (SqliteStatementProvider::migrateStatements() as $statement) { + foreach ($this->getStmtsProvider()->migrateStatements() as $statement) { $conn->executeStatement($statement); } @@ -64,7 +69,7 @@ protected function tearDown(): void { $conn = $this->getDoctrineDbalConnection(); - foreach (SqliteStatementProvider::rollbackStatements() as $statement) { + foreach ($this->getStmtsProvider()->rollbackStatements() as $statement) { $conn->executeStatement($statement); } @@ -72,4 +77,13 @@ protected function tearDown(): void parent::tearDown(); } + + private function getStmtsProvider(): DbalStatementsProvider + { + if ($this->stmtsProvider !== null) { + return $this->stmtsProvider; + } + + return $this->stmtsProvider = new DbalStatementsProvider($this->getDoctrineDbalConnection()); + } }