]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Constraint check Notice table, need to get foreign key array!
authorMikael Nordfeldth <mmn@hethane.se>
Thu, 31 Mar 2016 15:57:01 +0000 (17:57 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Thu, 31 Mar 2016 15:57:01 +0000 (17:57 +0200)
classes/Notice.php

index b387b627bf82bf75dc3bd201751081e172373ec9..81c3df63360d3a061d08433a3407e84c084af8e3 100644 (file)
@@ -3087,6 +3087,70 @@ class Notice extends Managed_DataObject
         $schema = Schema::get();
         $schemadef = $schema->getTableDef($table);
 
+        printfnq("\nConstraint checking Notice table...\n");
+        /**
+         *  Improve typing and make sure no NULL values in any id-related columns are 0
+         *  2016-03-31
+         */
+        foreach (['reply_to', 'repeat_of'] as $field) {
+            $notice = new Notice(); // reset the object
+            $notice->query(sprintf('UPDATE %1$s SET %2$s=NULL WHERE %2$s=0', $notice->escapedTableName(), $field));
+            // Now we're sure that no Notice entries have repeat_of=0, only an id > 0 or NULL
+            unset($notice);
+        }
+
+        /**
+         *  Make sure constraints are met before upgrading.
+         *  2016-03-31
+         *
+         *  Will find foreign keys which do not fulfill the constraints and fix
+         *  where appropriate, such as delete when "repeat_of" ID not found in notice.id
+         *  or set to NULL for "reply_to" in the same case.
+         *
+         *  XXX: How does this work if we would use multicolumn foreign keys?
+         */
+        foreach (['reply_to' => 'reset', 'repeat_of' => 'delete', 'profile' => 'delete'] as $field=>$action) {
+            $notice = new Notice();
+
+            $fkeyname = $notice->tableName().'_'.$field.'_fkey';
+            assert(isset($schemadef['foreign keys'][$fkeyname]) && $schemadef['foreign keys'][$fkeyname]);
+            $foreign_key = $schemadef['foreign keys'][$fkeyname];
+            printfnq("\n"._ve($schemadef));
+            $fkeytable = $foreign_key[0];
+            assert(isset($foreign_key[1][$field]));
+            $fkeycol   = $foreign_key[1][$field];
+
+            // NOTE: Above we set all repeat_of to NULL if they were 0, so this really gets them all.
+            $notice->whereAdd(sprintf('%1$s NOT IN (SELECT %2$s FROM %3$s)', $field, $fkeycol, $fkeytable));
+            if ($notice->find()) {
+                printfnq("\tFound {$notice->N} notices with {$field} NOT IN notice.id, {$action}ing...");
+                switch ($action) {
+                case 'delete':  // since it's a directly dependant notice for an unknown ID we don't want it in our DB
+                    while ($notice->fetch()) {
+                        // $notice->delete();
+                        printfnq("\n deleting {$notice->id}");
+                    }
+                    break;
+                case 'reset':   // just set it to NULL to be compatible with our constraints, if it was related to an unknown ID
+                    $ids = [];
+                    foreach ($notice->fetchAll('id') as $id) {
+                        settype($id, 'int');
+                        $ids[] = $id;
+                    }
+                    $notice = new Notice();
+                    $notice->query(sprintf('UPDATE %1$s SET %2$s=NULL WHERE id IN (%3$s)',
+                                        $notice->escapedTableName(),
+                                        $field,
+                                        implode(',', $ids)));
+                    break;
+                default:
+                    throw new ServerException('The programmer sucks, invalid action name when fixing table.');
+                }
+                printfnq("DONE.\n");
+            }
+            unset($notice);
+        }
+
         // 2015-09-04 We move Notice location data to Notice_location
         // First we see if we have to do this at all
         if (!isset($schemadef['fields']['lat'])