Separate workflow versionable data into workflow_version table

[MAILPOET-4430]
This commit is contained in:
David Remer
2022-08-03 08:29:42 +03:00
committed by Veljko V
parent c7f10a18c4
commit 964f3ca69d
2 changed files with 105 additions and 13 deletions

View File

@@ -29,6 +29,14 @@ class Migrator {
created_at timestamp NOT NULL, created_at timestamp NOT NULL,
updated_at timestamp NOT NULL, updated_at timestamp NOT NULL,
deleted_at timestamp NULL, deleted_at timestamp NULL,
PRIMARY KEY (id)
);
");
$this->runQuery("
CREATE TABLE {$this->prefix}workflow_versions (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
workflow_id int(11) unsigned NOT NULL,
trigger_keys longtext NOT NULL, trigger_keys longtext NOT NULL,
steps longtext, steps longtext,
PRIMARY KEY (id) PRIMARY KEY (id)
@@ -53,6 +61,7 @@ class Migrator {
$this->removeOldSchema(); $this->removeOldSchema();
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}workflows"); $this->runQuery("DROP TABLE IF EXISTS {$this->prefix}workflows");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}workflow_runs"); $this->runQuery("DROP TABLE IF EXISTS {$this->prefix}workflow_runs");
$this->runQuery("DROP TABLE IF EXISTS {$this->prefix}workflow_versions");
// clean Action Scheduler data // clean Action Scheduler data
$this->runQuery(" $this->runQuery("

View File

@@ -10,43 +10,80 @@ use wpdb;
class WorkflowStorage { class WorkflowStorage {
/** @var string */ /** @var string */
private $table; private $workflowTable;
/** @var string */
private $versionsTable;
/** @var wpdb */ /** @var wpdb */
private $wpdb; private $wpdb;
public function __construct() { public function __construct() {
global $wpdb; global $wpdb;
$this->table = $wpdb->prefix . 'mailpoet_workflows'; $this->workflowTable = $wpdb->prefix . 'mailpoet_workflows';
$this->versionsTable = $wpdb->prefix . 'mailpoet_workflow_versions';
$this->wpdb = $wpdb; $this->wpdb = $wpdb;
} }
public function createWorkflow(Workflow $workflow): int { public function createWorkflow(Workflow $workflow): int {
$result = $this->wpdb->insert($this->table, $workflow->toArray()); $result = $this->wpdb->insert($this->workflowTable, $this->workflowHeaderData($workflow));
if (!$result) { if (!$result) {
throw Exceptions::databaseError($this->wpdb->last_error); throw Exceptions::databaseError($this->wpdb->last_error);
} }
return $this->wpdb->insert_id; $id = (int)$this->wpdb->insert_id;
$this->insertWorkflowVersion($id, $workflow);
return $id;
} }
public function updateWorkflow(Workflow $workflow): void { public function updateWorkflow(Workflow $workflow): void {
$result = $this->wpdb->update($this->table, $workflow->toArray(), ['id' => $workflow->getId()]); $result = $this->wpdb->update($this->workflowTable, $this->workflowHeaderData($workflow), ['id' => $workflow->getId()]);
if ($result === false) { if ($result === false) {
throw Exceptions::databaseError($this->wpdb->last_error); throw Exceptions::databaseError($this->wpdb->last_error);
} }
$this->insertWorkflowVersion($workflow->getId(), $workflow);
} }
public function getWorkflow(int $id): ?Workflow { public function getWorkflow(int $id): ?Workflow {
$table = esc_sql($this->table); $workflowTable = esc_sql($this->workflowTable);
$query = (string)$this->wpdb->prepare("SELECT * FROM $table WHERE id = %d", $id); $versionTable = esc_sql($this->versionsTable);
$query = (string)$this->wpdb->prepare("
SELECT
workflow.*,
version.id AS version_id,
version.steps,
version.trigger_keys
FROM
$workflowTable as workflow,
$versionTable as version
WHERE
version.workflow_id = workflow.id
ORDER BY
version.id DESC
LIMIT
0,1; ",
$id
);
$data = $this->wpdb->get_row($query, ARRAY_A); $data = $this->wpdb->get_row($query, ARRAY_A);
return $data ? Workflow::fromArray((array)$data) : null; return $data ? Workflow::fromArray((array)$data) : null;
} }
/** @return Workflow[] */ /** @return Workflow[] */
public function getWorkflows(): array { public function getWorkflows(): array {
$table = esc_sql($this->table); $workflowTable = esc_sql($this->workflowTable);
$query = "SELECT * FROM $table ORDER BY id DESC"; $versionTable = esc_sql($this->versionsTable);
$query = "
SELECT
workflow.*,
version.id AS version_id,
version.steps,
version.trigger_keys
FROM
$workflowTable AS workflow
LEFT JOIN
$versionTable as version ON (version.workflow_id=workflow.id)
WHERE
version.id = (SELECT Max(id) FROM $versionTable WHERE workflow_id= version.workflow_id)
ORDER BY
workflow.id DESC; ";
$data = $this->wpdb->get_results($query, ARRAY_A); $data = $this->wpdb->get_results($query, ARRAY_A);
return array_map(function (array $workflowData) { return array_map(function (array $workflowData) {
return Workflow::fromArray($workflowData); return Workflow::fromArray($workflowData);
@@ -55,9 +92,20 @@ class WorkflowStorage {
/** @return string[] */ /** @return string[] */
public function getActiveTriggerKeys(): array { public function getActiveTriggerKeys(): array {
$table = esc_sql($this->table); $workflowTable = esc_sql($this->workflowTable);
$versionTable = esc_sql($this->versionsTable);
$query = (string)$this->wpdb->prepare( $query = (string)$this->wpdb->prepare(
"SELECT DISTINCT trigger_keys FROM $table WHERE status = %s", "
SELECT
DISTINCT version.trigger_keys
FROM
$workflowTable AS workflow,
$versionTable as version
WHERE
workflow.status = %s AND
workflow.id=version.workflow_id
ORDER BY
version.id DESC",
Workflow::STATUS_ACTIVE Workflow::STATUS_ACTIVE
); );
$result = $this->wpdb->get_col($query); $result = $this->wpdb->get_col($query);
@@ -73,9 +121,24 @@ class WorkflowStorage {
/** @return Workflow[] */ /** @return Workflow[] */
public function getActiveWorkflowsByTrigger(Trigger $trigger): array { public function getActiveWorkflowsByTrigger(Trigger $trigger): array {
$table = esc_sql($this->table); $workflowTable = esc_sql($this->workflowTable);
$versionTable = esc_sql($this->versionsTable);
$query = (string)$this->wpdb->prepare( $query = (string)$this->wpdb->prepare(
"SELECT * FROM $table WHERE status = %s AND trigger_keys LIKE %s", "
SELECT
workflow.*,
version.id AS version_id,
version.steps,
version.trigger_keys
FROM
$workflowTable AS workflow
LEFT JOIN
$versionTable as version ON (version.workflow_id=workflow.id)
WHERE
workflow.status = %s AND
version.trigger_keys LIKE %s AND
version.id = (SELECT Max(id) FROM $versionTable WHERE workflow_id= version.workflow_id)
",
Workflow::STATUS_ACTIVE, Workflow::STATUS_ACTIVE,
'%' . $this->wpdb->esc_like($trigger->getKey()) . '%' '%' . $this->wpdb->esc_like($trigger->getKey()) . '%'
); );
@@ -85,4 +148,24 @@ class WorkflowStorage {
return Workflow::fromArray($workflowData); return Workflow::fromArray($workflowData);
}, (array)$data); }, (array)$data);
} }
private function workflowHeaderData(Workflow $workflow): array {
$workflowHeader = $workflow->toArray();
unset($workflowHeader['steps']);
unset($workflowHeader['trigger_keys']);
return $workflowHeader;
}
private function insertWorkflowVersion(int $workflowId, Workflow $workflow): void {
$data = [
'workflow_id' => $workflowId,
'steps' => $workflow->toArray()['steps'],
'trigger_keys' => $workflow->toArray()['trigger_keys'],
];
$result = $this->wpdb->insert($this->versionsTable, $data);
if (!$result) {
throw Exceptions::databaseError($this->wpdb->last_error);
}
}
} }