xref: /webtrees/app/Schema/Migration39.php (revision e7f56f2af615447ab1a7646851f88b465ace9e04)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Schema;
19
20use Fisharebest\Webtrees\Database;
21use Fisharebest\Webtrees\DebugBar;
22use PDOException;
23
24/**
25 * Upgrade the database schema from version 39 to version 40.
26 */
27class Migration39 implements MigrationInterface
28{
29    /**
30     * Upgrade to to the next version
31     *
32     * @return void
33     */
34    public function upgrade()
35    {
36        // The following migrations were once part of the favorites module.
37
38        // Create the tables, as per PhpGedView 4.2.1
39        Database::exec(
40            "CREATE TABLE IF NOT EXISTS `##favorites` (" .
41            " fv_id       INTEGER AUTO_INCREMENT NOT NULL," .
42            " fv_username VARCHAR(32)            NOT NULL," .
43            " fv_gid      VARCHAR(20)                NULL," .
44            " fv_type     VARCHAR(15)                NULL," .
45            " fv_file     VARCHAR(100)               NULL," .
46            " fv_url      VARCHAR(255)               NULL," .
47            " fv_title    VARCHAR(255)               NULL," .
48            " fv_note     TEXT                       NULL," .
49            " PRIMARY KEY (fv_id)," .
50            "         KEY ix1 (fv_username)" .
51            ") COLLATE utf8_unicode_ci ENGINE=InnoDB"
52        );
53
54        // Add the new columns
55        try {
56            Database::exec(
57                "ALTER TABLE `##favorites`" .
58                " CHANGE fv_id    favorite_id   INTEGER AUTO_INCREMENT NOT NULL," .
59                " CHANGE fv_gid   xref          VARCHAR(20) NULL," .
60                " CHANGE fv_type  favorite_type ENUM('INDI', 'FAM', 'SOUR', 'REPO', 'OBJE', 'NOTE', 'URL') NOT NULL," .
61                " CHANGE fv_url   url           VARCHAR(255) NULL," .
62                " CHANGE fv_title title         VARCHAR(255) NULL," .
63                " CHANGE fv_note  note          VARCHAR(1000) NULL," .
64                " ADD user_id   INTEGER     NULL AFTER favorite_id," .
65                " ADD gedcom_id INTEGER NOT NULL AFTER user_id," .
66                " DROP KEY ix1," .
67                " ADD KEY news_ix1 (gedcom_id, user_id)"
68            );
69        } catch (PDOException $ex) {
70            DebugBar::addThrowable($ex);
71
72            // Already updated?
73        }
74
75        // Migrate data from the old columns to the new ones
76        try {
77            Database::exec(
78                "UPDATE `##favorites` f" .
79                " LEFT JOIN `##gedcom` g ON (f.fv_file    =g.gedcom_name)" .
80                " LEFT JOIN `##user`   u ON (f.fv_username=u.user_name)" .
81                " SET f.gedcom_id=g.gedcom_id, f.user_id=u.user_id"
82            );
83        } catch (PDOException $ex) {
84            DebugBar::addThrowable($ex);
85
86            // Already updated?
87        }
88
89        // Delete orphaned rows
90        Database::exec(
91            "DELETE FROM `##favorites` WHERE user_id IS NULL AND gedcom_id IS NULL"
92        );
93
94        // Delete the old column
95        try {
96            Database::exec(
97                "ALTER TABLE `##favorites` DROP fv_username, DROP fv_file"
98            );
99        } catch (PDOException $ex) {
100            DebugBar::addThrowable($ex);
101
102            // Already updated?
103        }
104
105        // Rename the table
106        try {
107            Database::exec(
108                "RENAME TABLE `##favorites` TO `##favorite`"
109            );
110        } catch (PDOException $ex) {
111            DebugBar::addThrowable($ex);
112
113            // Already updated?
114        }
115
116        // Add foreign key constraints
117        // Delete any data that might violate the new constraints
118        Database::exec(
119            "DELETE FROM `##favorite`" .
120            " WHERE user_id   NOT IN (SELECT user_id   FROM `##user`  )" .
121            " OR    gedcom_id NOT IN (SELECT gedcom_id FROM `##gedcom`)"
122        );
123
124        // Add the new constraints
125        try {
126            Database::exec(
127                "ALTER TABLE `##favorite`" .
128                " ADD FOREIGN KEY `##favorite_fk1` (user_id  ) REFERENCES `##user`   (user_id) ON DELETE CASCADE," .
129                " ADD FOREIGN KEY `##favorite_fk2` (gedcom_id) REFERENCES `##gedcom` (gedcom_id) ON DELETE CASCADE"
130            );
131        } catch (PDOException $ex) {
132            DebugBar::addThrowable($ex);
133
134            // Already updated?
135        }
136    }
137}
138