-
-
Notifications
You must be signed in to change notification settings - Fork 212
Database\Update::convertSingleField() overwrite changed values #6481
Comments
After a short review, the |
I need to improve my update check, I cannot go on the type only. Especially Theme+ 4.3 is dual compatible for 3.1 and 3.2 but use $desc = \Database::getInstance()->query('DESC ' . $table . ' file');
$stillNumericRecordCount = \Database::getInstance()
->query('SELECT COUNT(id) AS count FROM tl_theme_plus_stylesheet WHERE file REGEXP \'^[0-9]+$\'')
->count;
if ($desc->Type != 'binary(16)' || $stillNumericRecordCount) {
\Database\Updater::convertSingleField($table, 'file');
} |
Ich antworte mal auf Deutsch, damit es nicht durch die Übersetzung noch zusätzlich Verwirrung gibt. Ich bin auch der Meinung, dass die Lösung nicht optimal ist. Wir haben dazu schon in der AG Core diskutiert und auch auf dem Camp in großer und kleiner Runde. Leider haben wir keine bessere Lösung gefunden. Das Problem ist, dass die "fileTree"-Felder identifiziert werden müssen. Diese Information befindet sich in den DCA-Dateien, als müssen diese per Die einzige Alternative wäre, die DCA-Dateien als String einzulesen und mit einem PHP-Parser nach den "fileTree"-Feldern zu suchen. Da die DCA-Dateien aber sehr unterschiedlich ausfallen, ist das keine verlässliche Methode. Ich würde den Parsing-Ansatz trotzdem nochmal testen, wenn wir überwiegend der Meinung sind, dass wir das wollen. |
Ich bin absolut gegen ein parsing. Eine unzuverlässigere Variante ist schlimmer als wenn der Entwickler selber Hand anlegen muss... |
Vielleicht schaffen wir es ja gemeinsam, dass es eine zuverlässige Variante wird? |
Also es darf auf keinen Fall zu Datenverlust kommen, wenn die Methode mehrfach aufgerufen wird :-\ Eine Teillösung fällt mir gerade zum Überschreiben neuerer Werte ein: $objRow = $objDatabase->query(
"SELECT id, $backup FROM $table WHERE $field IS NULL AND $backup!=''"
); |
multiSRC nicht vergessen! |
Ich versteh nicht ganz die Aufregung, es war doch bisher immer die Aufgabe innerhalb der runonce selbst zu prüfen, ob ein Update/Migration nötig ist oder nicht. Mach ich jedenfalls seit Jahren so. Daher ist bei mir beispielsweise eine Repair Installation überhaupt kein Problem. Zu der anderen Geschichte, ihr sucht jetzt doch wieder nach einer Möglichkeit die externen Erweiterungen mit zu migrieren? Das geht doch gar nicht. Die SQL Definitionen in dessen DCA bleibt doch die alte. Der Vergleich beim DB aktualisieren würde doch sofort wieder zuschlagen und die Feldänderungen rückgängig machen wollen. |
Und noch n Test: https://gist.github.com/psi-4ward/7677634 @BugBuster1701 Das Problem ist das mehrfache ausführen der convertSingleField() Funktion(en). Machst du es öfters führt es zu Datenverlust. Die runonce wird ja bei jedem Update deiner Erweiterung wieder eingespielt und somit passiert genau das. |
@BugBuster1701 Es kann wohl kaum im Sinne der Extension Entwickler sein, dass wir alle unsere Runonces mit Prüfungen überladen müssen, die in der Im übrigen habe ich in Theme+ einen Spezialfall, das gebe ich ja zu. Mein Feld |
Wie gesagt, ich prüfe so etwas seit Jahren, ob das nun meine eigene Methode ist (die auch nie mehrmals ausgeführt werden darf) oder eine vom Core, da mache ich keinen Unterschied. Natürlich ist es von Vorteil, wenn die convert* Methoden das selber abfangen. |
Behoben in e3900ea. Vielen Dank für den Input und eure Zeit und nochmal Entschuldigung, dass wir uns von ein paar Wenigen trotz vieler Warnungen und Vorbehalte haben überreden lassen, die UUIDs im Binärformat zu speichern. |
…r methods are called multiple times (see #6481)
…r methods are called multiple times (see #6481)
Leider funktioniert die Lösung noch immer nicht: e3900ea#commitcomment-4727911 Hab es eben auch selbst getestet:
|
Die Lösung ist glaube ich ganz einfach: Wir müssen zuerst // SELECT UNHEX('39000000000000000000000000000000') AS val
rtrim($val, "\x00"); // string(1) "9"
// SELECT UNHEX('3981ad92585111e3aedaf5cf2c70ab0a') AS val
rtrim($val, "\x00"); // string(16) "9�’XQ�ã®ÚõÏ,p«
" |
Sollte in 4728431 behoben sein. Test-Ergebnis:
|
…r methods are called multiple times (see #6481)
The situation for extensions is a little bit different then for contao. Contao formally will check if the database upgrad to 3.2 is required and give this option only one time!
Extensions use the
runonce.php
which runs every time the extension is updated. According to #6459 (comment) such arunonce.php
may look like:Precondition:
for my test, I have added a stylesheet file to
tl_theme_plus_stylesheet
,here is the row (I have stripped unnecessary fields):
Now what will happen after the upgrade to 3.2 (the
runonce.php
is not executed)?What happen after the
runonce.php
run the first time?file_backup
is created, storing the original value andfile
will be filled with the file's uuid.PS: I replace the uuid with a human readable value just for this example.
Until now, everything is fine.
Now we work on the system, change the file selection and after some time, the row looks like this:
But now, we upgrade the extension and the
runonce.php
is executed a second time. What happen?Situation 1
Precondition: We change the selection on the field
file
.Precondition: We do not remove the
file_backup
field in the database backup.Let's have a look
After all, the row is:
As you can see, we lost the new selected value
file=67890
.Situation 2
Precondition: We change the selection on the field
file
.Precondition: We remove the file with the ID 21 from file manager.
Nearly the same as Situation 1 expect that the search for the previous value will not find the file record with ID 21. So the
file
field will be cleared:As you can see, we completely lost the
file
value.Situation 3
Precondition: We remove the
file_backup
field in the database backup.In short:
file_backup
.file_backup
.file
fieldThe row now looks like:
"ԥUV
, found nothing and resetfile
with NULL.Same as Situation 2, we completely lost the
file
value, also we lost the originalfile_backup
value.Conclusion
The
Database\Update::convertSingleField()
must check if the update is realy necessary. I don't see the point why every extension need to do the same check.Hotfix for developers
Developers need to check if the update is necessary, like this:
Hint: please see #6481 (comment) for more details!
The text was updated successfully, but these errors were encountered: