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

Umsetzung von Collection-NestedSet-Struktur mit DoctrineExtensions #220

Open
j3nsch opened this issue Dec 9, 2021 · 4 comments · May be fixed by #227
Open

Umsetzung von Collection-NestedSet-Struktur mit DoctrineExtensions #220

j3nsch opened this issue Dec 9, 2021 · 4 comments · May be fixed by #227
Assignees

Comments

@j3nsch
Copy link
Member

j3nsch commented Dec 9, 2021

Die Sammlungen (Collection) Objekte bilden in der Datenbank eine Baumstruktur ab. Dafür haben wir eine eigenen NestedSet Implementation. In Issue #131 geht es um die Umstellung auf Doctrine im Allgemeinen. Hier in diesem Ticket geht es darum, zu probieren unsere eigenen Implementation durch Doctrine Extensions abzulösen. Das würde unseren Code reduzieren und die Collection-Klasse könnte vollständig mit Doctrine-ORM umgesetzt werden.

Leider benötigt die aktuelle Version der Doctrine Extensions mindestens PHP 7.2. Wir können aber erst mit Laminas und OPUS 4 v5.1 auf neuere PHP Versionen umsteigen. Eine ältere Version der Extensions führt dazu, dass auch andere Doctrine Abhängigkeiten zu wesentlich älteren Versionen zurückgestuft werden müssen und das scheint nicht sinnvoll. Der Umstieg auf die Extensions sollte auf jeden Fall für später getestet werden.

@j3nsch
Copy link
Member Author

j3nsch commented Dec 9, 2021

Ich würde vorschlagen entweder jetzt hier noch weiter zu experimentieren oder zumindest alle bisherigen Erkenntnisse festzuhalten, um den Wiedereinstieg später zu vereinfachen. Die Ergebnisse in einem Branch festgehalten werden. Der Branch könnte für eine neuere PHP Version konfiguriert werden, allerdings haben wir immer noch ZF1 Abhängigkeiten, der Grund für unsere Beschränkung auf PHP 7.1.

@j3nsch j3nsch added this to the Framework 5.1 milestone Dec 9, 2021
extracts added a commit that referenced this issue Dec 10, 2021
…ctrine ORM (using the Doctrine "Tree" extension to implement nested-set behavior)
j3nsch added a commit that referenced this issue Jan 5, 2022
j3nsch added a commit that referenced this issue Jan 5, 2022
@j3nsch
Copy link
Member Author

j3nsch commented Feb 8, 2022

Mit Vagrant können wir hier jetzt sehr leicht eine Umgebung mit PHP 7.3 oder neuer aufsetzen, um die Umsetzung mit DoctrineExtensions zu testen. Im Idealfall kann der Code dann später mit OPUS 4 v5.1 übernommen werden.

extracts added a commit that referenced this issue Feb 10, 2022
extracts added a commit that referenced this issue Feb 11, 2022
extracts added a commit that referenced this issue Feb 17, 2022
…n; this prevents some tests from throwing Doctrine exceptions due to the CollectionRole->rootCollection relationship currently not being set to cascade persist
extracts added a commit that referenced this issue Feb 17, 2022
extracts added a commit that referenced this issue Feb 17, 2022
…ses the children() function of the Doctrine Tree extension to return the direct children of a Collection instance
extracts added a commit that referenced this issue Feb 17, 2022
extracts added a commit that referenced this issue Feb 24, 2022
extracts added a commit that referenced this issue Feb 24, 2022
extracts added a commit that referenced this issue Feb 24, 2022
…role relationship is set for the root collection
extracts added a commit that referenced this issue Feb 24, 2022
… root collection also deletes (or stores) its entire children tree
@extracts
Copy link
Contributor

Ich habe zwei Tests (testDeleteChildren() und testStoreChildren()) hinzugefügt, die das Löschen/Speichern von Child-Objekten testen, wenn die Parent-Collection gelöscht/gespeichert wird.

Momentan schlägt der testDeleteChildren() Test beim Aufruf von $root->delete(); fehl. Dies liegt daran, dass im SQL Schema die FOREIGN KEY CONSTRAINTs mit der Cascade-Rule RESTRICT bzw. dem Default-Wert (NO ACTION welcher äquivalent zu RESTRICT ist) angegeben sind:

| collections | CREATE TABLE `collections` (
  [...]
  CONSTRAINT `collections_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `collections_roles` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
  CONSTRAINT `collections_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `collections` (`id`)
) ENGINE=InnoDB [...] |

Die MySQL-Doku sagt für RESTRICT:

RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.

Oder für unseren Fall formuliert (see also):

if a particular primary key ID (i.e. id) value in the COLLECTION table is deleted, this action shall be prevented (i.e. "RESTRICTed") if there is any row in the COLLECTION table which has a foreign key (i.e. parent_id value) that matches the value of the COLLECTION table ID value.

So wie ich es aber verstanden habe, wollen wir stattdessen dieses Verhalten:

Wenn eine Parent-Collection gelöscht wird, so werden auch dessen Child-Objekte gelöscht. Für dieses Verhalten müsste das SQL Schema wie folgt geändert werden:

| collections | CREATE TABLE `collections` (
  [...]
  CONSTRAINT `collections_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `collections_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `collections_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `collections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB [...] |

Ich habe dies in meiner lokalen Installation einmal ausprobiert:

ALTER TABLE `collections` DROP FOREIGN KEY `collections_ibfk_1`;
ALTER TABLE `collections` DROP FOREIGN KEY `collections_ibfk_2`;
ALTER TABLE `collections` ADD CONSTRAINT `collections_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `collections_roles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `collections` ADD CONSTRAINT `collections_ibfk_2` FOREIGN KEY (`parent_id`) REFERENCES `collections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Mit diesen Schema-Änderungen und den Änderungen in Branch issue220 laufen die oben erwähnten Tests erfolgreich durch.

Dabei werden auch die für die "nested set" Struktur erforderlichen DB-Felder (left_id, right_id & parent_id) durch die Doctrine Tree Extension korrekt gesetzt und beim Löschen von Objekten auch aktualisiert.

@j3nsch j3nsch removed this from the Framework 5.1 milestone Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants