xref: /plugin/davcal/vendor/sabre/dav/bin/migrateto21.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler#!/usr/bin/env php
2*a1a3b679SAndreas Boehler<?php
3*a1a3b679SAndreas Boehler
4*a1a3b679SAndreas Boehlerecho "SabreDAV migrate script for version 2.1\n";
5*a1a3b679SAndreas Boehler
6*a1a3b679SAndreas Boehlerif ($argc<2) {
7*a1a3b679SAndreas Boehler
8*a1a3b679SAndreas Boehler    echo <<<HELLO
9*a1a3b679SAndreas Boehler
10*a1a3b679SAndreas BoehlerThis script help you migrate from a pre-2.1 database to 2.1.
11*a1a3b679SAndreas Boehler
12*a1a3b679SAndreas BoehlerChanges:
13*a1a3b679SAndreas Boehler  The 'calendarobjects' table will be upgraded.
14*a1a3b679SAndreas Boehler  'schedulingobjects' will be created.
15*a1a3b679SAndreas Boehler
16*a1a3b679SAndreas BoehlerIf you don't use the default PDO CalDAV or CardDAV backend, it's pointless to
17*a1a3b679SAndreas Boehlerrun this script.
18*a1a3b679SAndreas Boehler
19*a1a3b679SAndreas BoehlerKeep in mind that ALTER TABLE commands will be executed. If you have a large
20*a1a3b679SAndreas Boehlerdataset this may mean that this process takes a while.
21*a1a3b679SAndreas Boehler
22*a1a3b679SAndreas BoehlerLastly: Make a back-up first. This script has been tested, but the amount of
23*a1a3b679SAndreas Boehlerpotential variants are extremely high, so it's impossible to deal with every
24*a1a3b679SAndreas Boehlerpossible situation.
25*a1a3b679SAndreas Boehler
26*a1a3b679SAndreas BoehlerIn the worst case, you will lose all your data. This is not an overstatement.
27*a1a3b679SAndreas Boehler
28*a1a3b679SAndreas BoehlerUsage:
29*a1a3b679SAndreas Boehler
30*a1a3b679SAndreas Boehlerphp {$argv[0]} [pdo-dsn] [username] [password]
31*a1a3b679SAndreas Boehler
32*a1a3b679SAndreas BoehlerFor example:
33*a1a3b679SAndreas Boehler
34*a1a3b679SAndreas Boehlerphp {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
35*a1a3b679SAndreas Boehlerphp {$argv[0]} sqlite:data/sabredav.db
36*a1a3b679SAndreas Boehler
37*a1a3b679SAndreas BoehlerHELLO;
38*a1a3b679SAndreas Boehler
39*a1a3b679SAndreas Boehler    exit();
40*a1a3b679SAndreas Boehler
41*a1a3b679SAndreas Boehler}
42*a1a3b679SAndreas Boehler
43*a1a3b679SAndreas Boehler// There's a bunch of places where the autoloader could be, so we'll try all of
44*a1a3b679SAndreas Boehler// them.
45*a1a3b679SAndreas Boehler$paths = [
46*a1a3b679SAndreas Boehler    __DIR__ . '/../vendor/autoload.php',
47*a1a3b679SAndreas Boehler    __DIR__ . '/../../../autoload.php',
48*a1a3b679SAndreas Boehler];
49*a1a3b679SAndreas Boehler
50*a1a3b679SAndreas Boehlerforeach($paths as $path) {
51*a1a3b679SAndreas Boehler    if (file_exists($path)) {
52*a1a3b679SAndreas Boehler        include $path;
53*a1a3b679SAndreas Boehler        break;
54*a1a3b679SAndreas Boehler    }
55*a1a3b679SAndreas Boehler}
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler$dsn = $argv[1];
58*a1a3b679SAndreas Boehler$user = isset($argv[2])?$argv[2]:null;
59*a1a3b679SAndreas Boehler$pass = isset($argv[3])?$argv[3]:null;
60*a1a3b679SAndreas Boehler
61*a1a3b679SAndreas Boehlerecho "Connecting to database: " . $dsn . "\n";
62*a1a3b679SAndreas Boehler
63*a1a3b679SAndreas Boehler$pdo = new PDO($dsn, $user, $pass);
64*a1a3b679SAndreas Boehler$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
65*a1a3b679SAndreas Boehler$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
66*a1a3b679SAndreas Boehler
67*a1a3b679SAndreas Boehler$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
68*a1a3b679SAndreas Boehler
69*a1a3b679SAndreas Boehlerswitch($driver) {
70*a1a3b679SAndreas Boehler
71*a1a3b679SAndreas Boehler    case 'mysql' :
72*a1a3b679SAndreas Boehler        echo "Detected MySQL.\n";
73*a1a3b679SAndreas Boehler        break;
74*a1a3b679SAndreas Boehler    case 'sqlite' :
75*a1a3b679SAndreas Boehler        echo "Detected SQLite.\n";
76*a1a3b679SAndreas Boehler        break;
77*a1a3b679SAndreas Boehler    default :
78*a1a3b679SAndreas Boehler        echo "Error: unsupported driver: " . $driver . "\n";
79*a1a3b679SAndreas Boehler        die(-1);
80*a1a3b679SAndreas Boehler}
81*a1a3b679SAndreas Boehler
82*a1a3b679SAndreas Boehlerecho "Upgrading 'calendarobjects'\n";
83*a1a3b679SAndreas Boehler$addUid = false;
84*a1a3b679SAndreas Boehlertry {
85*a1a3b679SAndreas Boehler    $result = $pdo->query('SELECT * FROM calendarobjects LIMIT 1');
86*a1a3b679SAndreas Boehler    $row = $result->fetch(\PDO::FETCH_ASSOC);
87*a1a3b679SAndreas Boehler
88*a1a3b679SAndreas Boehler    if (!$row) {
89*a1a3b679SAndreas Boehler        echo "No data in table. Going to try to add the uid field anyway.\n";
90*a1a3b679SAndreas Boehler        $addUid = true;
91*a1a3b679SAndreas Boehler    } elseif (array_key_exists('uid', $row)) {
92*a1a3b679SAndreas Boehler        echo "uid field exists. Assuming that this part of the migration has\n";
93*a1a3b679SAndreas Boehler        echo "Already been completed.\n";
94*a1a3b679SAndreas Boehler    } else {
95*a1a3b679SAndreas Boehler        echo "2.0 schema detected.\n";
96*a1a3b679SAndreas Boehler        $addUid = true;
97*a1a3b679SAndreas Boehler    }
98*a1a3b679SAndreas Boehler
99*a1a3b679SAndreas Boehler} catch (Exception $e) {
100*a1a3b679SAndreas Boehler    echo "Could not find a calendarobjects table. Skipping this part of the\n";
101*a1a3b679SAndreas Boehler    echo "upgrade.\n";
102*a1a3b679SAndreas Boehler}
103*a1a3b679SAndreas Boehler
104*a1a3b679SAndreas Boehlerif ($addUid) {
105*a1a3b679SAndreas Boehler
106*a1a3b679SAndreas Boehler    switch($driver) {
107*a1a3b679SAndreas Boehler        case 'mysql' :
108*a1a3b679SAndreas Boehler            $pdo->exec('ALTER TABLE calendarobjects ADD uid VARCHAR(200)');
109*a1a3b679SAndreas Boehler            break;
110*a1a3b679SAndreas Boehler        case 'sqlite' :
111*a1a3b679SAndreas Boehler            $pdo->exec('ALTER TABLE calendarobjects ADD uid TEXT');
112*a1a3b679SAndreas Boehler            break;
113*a1a3b679SAndreas Boehler    }
114*a1a3b679SAndreas Boehler
115*a1a3b679SAndreas Boehler    $result = $pdo->query('SELECT id, calendardata FROM calendarobjects');
116*a1a3b679SAndreas Boehler    $stmt = $pdo->prepare('UPDATE calendarobjects SET uid = ? WHERE id = ?');
117*a1a3b679SAndreas Boehler    $counter = 0;
118*a1a3b679SAndreas Boehler
119*a1a3b679SAndreas Boehler    while($row = $result->fetch(\PDO::FETCH_ASSOC)) {
120*a1a3b679SAndreas Boehler
121*a1a3b679SAndreas Boehler        try {
122*a1a3b679SAndreas Boehler            $vobj = \Sabre\VObject\Reader::read($row['calendardata']);
123*a1a3b679SAndreas Boehler        } catch (\Exception $e) {
124*a1a3b679SAndreas Boehler            echo "Warning! Item with id $row[id] could not be parsed!\n";
125*a1a3b679SAndreas Boehler            continue;
126*a1a3b679SAndreas Boehler        }
127*a1a3b679SAndreas Boehler        $uid = null;
128*a1a3b679SAndreas Boehler        $item = $vobj->getBaseComponent();
129*a1a3b679SAndreas Boehler        if (!isset($item->UID)) {
130*a1a3b679SAndreas Boehler            echo "Warning! Item with id $item[id] does NOT have a UID property and this is required.\n";
131*a1a3b679SAndreas Boehler            continue;
132*a1a3b679SAndreas Boehler        }
133*a1a3b679SAndreas Boehler        $uid = (string)$item->UID;
134*a1a3b679SAndreas Boehler        $stmt->execute([$uid, $row['id']]);
135*a1a3b679SAndreas Boehler        $counter++;
136*a1a3b679SAndreas Boehler
137*a1a3b679SAndreas Boehler    }
138*a1a3b679SAndreas Boehler
139*a1a3b679SAndreas Boehler}
140*a1a3b679SAndreas Boehler
141*a1a3b679SAndreas Boehlerecho "Creating 'schedulingobjects'\n";
142*a1a3b679SAndreas Boehler
143*a1a3b679SAndreas Boehlerswitch($driver) {
144*a1a3b679SAndreas Boehler
145*a1a3b679SAndreas Boehler    case 'mysql' :
146*a1a3b679SAndreas Boehler        $pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects
147*a1a3b679SAndreas Boehler(
148*a1a3b679SAndreas Boehler    id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
149*a1a3b679SAndreas Boehler    principaluri VARCHAR(255),
150*a1a3b679SAndreas Boehler    calendardata MEDIUMBLOB,
151*a1a3b679SAndreas Boehler    uri VARCHAR(200),
152*a1a3b679SAndreas Boehler    lastmodified INT(11) UNSIGNED,
153*a1a3b679SAndreas Boehler    etag VARCHAR(32),
154*a1a3b679SAndreas Boehler    size INT(11) UNSIGNED NOT NULL
155*a1a3b679SAndreas Boehler) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
156*a1a3b679SAndreas Boehler        ');
157*a1a3b679SAndreas Boehler        break;
158*a1a3b679SAndreas Boehler
159*a1a3b679SAndreas Boehler
160*a1a3b679SAndreas Boehler    case 'sqlite' :
161*a1a3b679SAndreas Boehler        $pdo->exec('CREATE TABLE IF NOT EXISTS schedulingobjects (
162*a1a3b679SAndreas Boehler    id integer primary key asc,
163*a1a3b679SAndreas Boehler    principaluri text,
164*a1a3b679SAndreas Boehler    calendardata blob,
165*a1a3b679SAndreas Boehler    uri text,
166*a1a3b679SAndreas Boehler    lastmodified integer,
167*a1a3b679SAndreas Boehler    etag text,
168*a1a3b679SAndreas Boehler    size integer
169*a1a3b679SAndreas Boehler)
170*a1a3b679SAndreas Boehler');
171*a1a3b679SAndreas Boehler        break;
172*a1a3b679SAndreas Boehler        $pdo->exec('
173*a1a3b679SAndreas Boehler            CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);
174*a1a3b679SAndreas Boehler        ');
175*a1a3b679SAndreas Boehler        break;
176*a1a3b679SAndreas Boehler}
177*a1a3b679SAndreas Boehler
178*a1a3b679SAndreas Boehlerecho "Done.\n";
179*a1a3b679SAndreas Boehler
180*a1a3b679SAndreas Boehlerecho "Upgrade to 2.1 schema completed.\n";
181