Skip to content

Commit

Permalink
SqlGenerator - Add FKs after tables instead of sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
colemanw committed Mar 26, 2024
1 parent 0238b45 commit ee4a4e7
Showing 1 changed file with 25 additions and 31 deletions.
56 changes: 25 additions & 31 deletions Civi/Schema/SqlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class SqlGenerator {
private array $entities;

public function __construct(array $entities) {
$this->entities = $this->sortEntitiesByForeignKey($entities);
$this->entities = $entities;
}

public function getEntitiesSortedByForeignKey(): array {
public function getEntities(): array {
return $this->entities;
}

Expand All @@ -33,43 +33,27 @@ public function getCreateTablesSql(): string {
foreach ($this->entities as $entity) {
$sql .= $this->generateCreateTableSql($entity);
}
foreach ($this->entities as $entity) {
$sql .= $this->generateConstraintsSql($entity);
}
return $sql;
}

public function getCreateTableSql(string $entityName): string {
return $this->generateCreateTableSql($this->entities[$entityName]);
$sql = $this->generateCreateTableSql($this->entities[$entityName]);
$sql .= $this->generateConstraintsSql($this->entities[$entityName]);
return $sql;
}

public function getDropTablesSql(): string {
$sql = "SET FOREIGN_KEY_CHECKS=0;\n";
foreach (array_reverse($this->entities) as $entity) {
foreach ($this->entities as $entity) {
$sql .= "DROP TABLE IF EXISTS `{$entity['table']}`;\n";
}
$sql .= "SET FOREIGN_KEY_CHECKS=1;\n";
return $sql;
}

private function sortEntitiesByForeignKey(array $entities): array {
$entities = array_column($entities, NULL, 'name');
$sorter = new FixedArraySort();
foreach ($entities as $name => $entity) {
$references = [];
foreach ($entity['getFields']() as $field) {
$reference = $field['entity_reference']['entity'] ?? NULL;
if ($reference && $reference !== $name && isset($entities[$reference])) {
$references[] = $reference;
}
}
$sorter->add($name, $references);
}
$sortedEntityNames = $sorter->sort();
$sortedEntities = [];
foreach ($sortedEntityNames as $name) {
$sortedEntities[$name] = $entities[$name];
}
return $sortedEntities;
}

private function generateCreateTableSql(array $entity): string {
$definition = [];
$primaryKeys = [];
Expand Down Expand Up @@ -104,18 +88,28 @@ private function generateCreateTableSql(array $entity): string {
}
$definition[] = (!empty($index['unique']) ? 'UNIQUE ' : '') . "INDEX `$indexName`(" . implode(', ', $indexFields) . ')';
}

$sql = "CREATE TABLE `{$entity['table']}` (\n " .
implode(",\n ", $definition) .
"\n)\n" .
$this->getTableOptions() . ";\n";
return $sql;
}

private function generateConstraintsSql(array $entity): string {
$constraints = [];
foreach ($entity['getFields']() as $fieldName => $field) {
if (!empty($field['entity_reference']['entity'])) {
$definition[] = "CONSTRAINT `FK_{$entity['table']}_$fieldName` FOREIGN KEY (`$fieldName`)" .
$constraints[] = "ADD CONSTRAINT `FK_{$entity['table']}_$fieldName` FOREIGN KEY (`$fieldName`)" .
" REFERENCES `" . $this->getTableForEntity($field['entity_reference']['entity']) . "`(`{$field['entity_reference']['key']}`)" .
" ON DELETE {$field['entity_reference']['on_delete']}";
}
}

$sql = "CREATE TABLE `{$entity['table']}` (\n " .
implode(",\n ", $definition) .
"\n)\n" .
$this->getTableOptions() . ";\n";
$sql = '';
if ($constraints) {
$sql .= "ALTER TABLE `{$entity['table']}`\n ";
$sql .= implode(",\n ", $constraints) . ";\n";
}
return $sql;
}

Expand Down

0 comments on commit ee4a4e7

Please sign in to comment.